staging: ath6kl: s|A_MEMCPY|memcpy|g
[deliverable/linux.git] / 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_types.h"
30 #include "a_osapi.h"
31 #include "htc_api.h"
32 #include "wmi.h"
33 #include "a_drv.h"
34 #include "hif.h"
35 #include "common_drv.h"
36 #include "a_debug.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)
41 #else
42 #include "ar6000_drv.h"
43 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
44
45 #ifdef ATH_AR6K_ENABLE_GMBOX
46 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
47 #include "export_hci_transport.h"
48 #else
49 #include "hci_transport_api.h"
50 #endif
51 #include "epping_test.h"
52 #include "gmboxif.h"
53 #include "ar3kconfig.h"
54 #include <net/bluetooth/bluetooth.h>
55 #include <net/bluetooth/hci_core.h>
56
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
60 #endif
61
62 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
63 unsigned int ar3khcibaud = 0;
64 unsigned int hciuartscale = 0;
65 unsigned int hciuartstep = 0;
66
67 module_param(ar3khcibaud, int, 0644);
68 module_param(hciuartscale, int, 0644);
69 module_param(hciuartstep, int, 0644);
70 #else
71 extern unsigned int ar3khcibaud;
72 extern unsigned int hciuartscale;
73 extern unsigned int hciuartstep;
74 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
75
76 typedef struct {
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;
83 u8 *pHTCStructAlloc;
84 spinlock_t BridgeLock;
85 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
86 HCI_TRANSPORT_MISC_HANDLES HCITransHdl;
87 #else
88 AR_SOFTC_T *ar;
89 #endif /* EXPORT_HCI_BRIDGE_INTERFACE */
90 } AR6K_HCI_BRIDGE_INFO;
91
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)
99
100 #define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0]))
101
102 extern unsigned int setupbtdev;
103 AR3K_CONFIG_INFO ar3kconfig;
104
105 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
106 AR6K_HCI_BRIDGE_INFO *g_pHcidevInfo;
107 #endif
108
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);
117
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);
122 #else
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 */
128
129 #define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock)
130 #define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock)
131
132 static inline void FreeBtOsBuf(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, void *osbuf)
133 {
134 if (pHcidevInfo->HciNormalMode) {
135 bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf);
136 } else {
137 /* in test mode, these are just ordinary netbuf allocations */
138 A_NETBUF_FREE(osbuf);
139 }
140 }
141
142 static void FreeHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HTC_PACKET *pPacket)
143 {
144 LOCK_BRIDGE(pHcidevInfo);
145 HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket);
146 UNLOCK_BRIDGE(pHcidevInfo);
147 }
148
149 static HTC_PACKET * AllocHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
150 {
151 HTC_PACKET *pPacket = NULL;
152 LOCK_BRIDGE(pHcidevInfo);
153 pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead);
154 UNLOCK_BRIDGE(pHcidevInfo);
155 return pPacket;
156 }
157
158 #define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1))
159
160 static void RefillRecvBuffers(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
161 HCI_TRANSPORT_PACKET_TYPE Type,
162 int NumBuffers)
163 {
164 int length, i;
165 void *osBuf = NULL;
166 HTC_PACKET_QUEUE queue;
167 HTC_PACKET *pPacket;
168
169 INIT_HTC_PACKET_QUEUE(&queue);
170
171 if (Type == HCI_ACL_TYPE) {
172 if (pHcidevInfo->HciNormalMode) {
173 length = HCI_MAX_FRAME_SIZE;
174 } else {
175 length = MAX_ACL_RECV_LENGTH;
176 }
177 } else {
178 length = MAX_EVT_RECV_LENGTH;
179 }
180
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);
185
186 for (i = 0; i < NumBuffers; i++) {
187
188 if (pHcidevInfo->HciNormalMode) {
189 osBuf = bt_alloc_buffer(pHcidevInfo,length);
190 } else {
191 osBuf = A_NETBUF_ALLOC(length);
192 }
193
194 if (NULL == osBuf) {
195 break;
196 }
197
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"));
202 break;
203 }
204
205 SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type);
206 /* add to queue */
207 HTC_PACKET_ENQUEUE(&queue,pPacket);
208 }
209
210 if (i > 0) {
211 HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue);
212 }
213 }
214
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,
220 void *pContext)
221 {
222 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
223 int status;
224 u32 address, hci_uart_pwr_mgmt_params;
225 // AR3K_CONFIG_INFO ar3kconfig;
226
227 pHcidevInfo->pHCIDev = HCIHandle;
228
229 memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps));
230
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));
236
237 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
238 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len);
239 #else
240 A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len);
241 #endif
242
243 /* provide buffers */
244 RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS);
245 RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS);
246
247 do {
248 /* start transport */
249 status = HCI_TransportStart(pHcidevInfo->pHCIDev);
250
251 if (status) {
252 break;
253 }
254
255 if (!pHcidevInfo->HciNormalMode) {
256 /* in test mode, no need to go any further */
257 break;
258 }
259
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)
263 // FIXME
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
267 A_MDELAY(100);
268
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);
274 #else
275 ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice;
276 #endif
277 ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev;
278
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;
284 }
285
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;
291 }
292
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);
297 if (0 == status) {
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;
301 } else {
302 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n"));
303 }
304 /* configure the AR3K device */
305 memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6);
306 status = AR3KConfigure(&ar3kconfig);
307 if (status) {
308 break;
309 }
310
311 /* Make sure both AR6K and AR3K have power management enabled */
312 if (ar3kconfig.PwrMgmtEnabled) {
313 status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true);
314 if (status) {
315 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n"));
316 }
317 }
318
319 status = bt_register_hci(pHcidevInfo);
320
321 } while (false);
322
323 return status;
324 }
325
326 static void ar6000_hci_transport_failure(void *pContext, int Status)
327 {
328 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
329
330 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n"));
331
332 if (pHcidevInfo->HciNormalMode) {
333 /* TODO .. */
334 }
335 }
336
337 static void ar6000_hci_transport_removed(void *pContext)
338 {
339 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
340
341 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n"));
342
343 A_ASSERT(pHcidevInfo->pHCIDev != NULL);
344
345 HCI_TransportDetach(pHcidevInfo->pHCIDev);
346 bt_cleanup_hci(pHcidevInfo);
347 pHcidevInfo->pHCIDev = NULL;
348 }
349
350 static void ar6000_hci_send_complete(void *pContext, HTC_PACKET *pPacket)
351 {
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);
356
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));
360 }
361 }
362
363 FreeHTCStruct(pHcidevInfo,pPacket);
364 FreeBtOsBuf(pHcidevInfo,osbuf);
365
366 }
367
368 static void ar6000_hci_pkt_recv(void *pContext, HTC_PACKET *pPacket)
369 {
370 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
371 struct sk_buff *skb;
372
373 A_ASSERT(pHcidevInfo != NULL);
374 skb = (struct sk_buff *)pPacket->pPktContext;
375 A_ASSERT(skb != NULL);
376
377 do {
378
379 if (pPacket->Status) {
380 break;
381 }
382
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));
386
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);
391
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",
395 skb->len));
396 AR_DEBUG_PRINTBUF(skb->data, skb->len,"BT HCI RECV Packet Dump");
397 }
398
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 */
403 skb = NULL;
404 }
405 break;
406 }
407
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));
413 #else
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);
417 #endif
418 netif_rx(skb);
419 skb = NULL;
420 }
421
422 } while (false);
423
424 FreeHTCStruct(pHcidevInfo,pPacket);
425
426 if (skb != NULL) {
427 /* packet was not accepted, free it */
428 FreeBtOsBuf(pHcidevInfo,skb);
429 }
430
431 }
432
433 static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable)
434 {
435 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
436 int refillCount;
437
438 if (Type == HCI_ACL_TYPE) {
439 refillCount = MAX_ACL_RECV_BUFS - BuffersAvailable;
440 } else {
441 refillCount = MAX_EVT_RECV_BUFS - BuffersAvailable;
442 }
443
444 if (refillCount > 0) {
445 RefillRecvBuffers(pHcidevInfo,Type,refillCount);
446 }
447
448 }
449
450 static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, HTC_PACKET *pPacket)
451 {
452 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext;
453 HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP;
454
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;
460 }
461 }
462
463 return action;
464 }
465
466 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
467 int ar6000_setup_hci(void *ar)
468 #else
469 int ar6000_setup_hci(AR_SOFTC_T *ar)
470 #endif
471 {
472 HCI_TRANSPORT_CONFIG_INFO config;
473 int status = 0;
474 int i;
475 HTC_PACKET *pPacket;
476 AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
477
478
479 do {
480
481 pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)A_MALLOC(sizeof(AR6K_HCI_BRIDGE_INFO));
482
483 if (NULL == pHcidevInfo) {
484 status = A_NO_MEMORY;
485 break;
486 }
487
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;
492 #else
493 ar->hcidev_info = pHcidevInfo;
494 pHcidevInfo->ar = ar;
495 #endif
496 spin_lock_init(&pHcidevInfo->BridgeLock);
497 INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead);
498
499 ar->exitCallback = AR3KConfigureExit;
500
501 status = bt_setup_hci(pHcidevInfo);
502 if (status) {
503 break;
504 }
505
506 if (pHcidevInfo->HciNormalMode) {
507 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n"));
508 } else {
509 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n"));
510 }
511
512 pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS);
513
514 if (NULL == pHcidevInfo->pHTCStructAlloc) {
515 status = A_NO_MEMORY;
516 break;
517 }
518
519 pPacket = (HTC_PACKET *)pHcidevInfo->pHTCStructAlloc;
520 for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) {
521 FreeHTCStruct(pHcidevInfo,pPacket);
522 }
523
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;
536
537 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
538 pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config);
539 #else
540 pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config);
541 #endif
542
543 if (NULL == pHcidevInfo->pHCIDev) {
544 status = A_ERROR;
545 }
546
547 } while (false);
548
549 if (status) {
550 if (pHcidevInfo != NULL) {
551 if (NULL == pHcidevInfo->pHCIDev) {
552 /* GMBOX may not be present in older chips */
553 /* just return success */
554 status = 0;
555 }
556 }
557 ar6000_cleanup_hci(ar);
558 }
559
560 return status;
561 }
562
563 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
564 void ar6000_cleanup_hci(void *ar)
565 #else
566 void ar6000_cleanup_hci(AR_SOFTC_T *ar)
567 #endif
568 {
569 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
570 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = g_pHcidevInfo;
571 #else
572 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
573 #endif
574
575 if (pHcidevInfo != NULL) {
576 bt_cleanup_hci(pHcidevInfo);
577
578 if (pHcidevInfo->pHCIDev != NULL) {
579 HCI_TransportStop(pHcidevInfo->pHCIDev);
580 HCI_TransportDetach(pHcidevInfo->pHCIDev);
581 pHcidevInfo->pHCIDev = NULL;
582 }
583
584 if (pHcidevInfo->pHTCStructAlloc != NULL) {
585 A_FREE(pHcidevInfo->pHTCStructAlloc);
586 pHcidevInfo->pHTCStructAlloc = NULL;
587 }
588
589 A_FREE(pHcidevInfo);
590 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
591 ar->hcidev_info = NULL;
592 #endif
593 }
594
595
596 }
597
598 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
599 int hci_test_send(void *ar, struct sk_buff *skb)
600 #else
601 int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb)
602 #endif
603 {
604 int status = 0;
605 int length;
606 EPPING_HEADER *pHeader;
607 HTC_PACKET *pPacket;
608 HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG;
609 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
610 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = g_pHcidevInfo;
611 #else
612 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
613 #endif
614
615 do {
616
617 if (NULL == pHcidevInfo) {
618 status = A_ERROR;
619 break;
620 }
621
622 if (NULL == pHcidevInfo->pHCIDev) {
623 status = A_ERROR;
624 break;
625 }
626
627 if (pHcidevInfo->HciNormalMode) {
628 /* this interface cannot run when normal WMI is running */
629 status = A_ERROR;
630 break;
631 }
632
633 pHeader = (EPPING_HEADER *)A_NETBUF_DATA(skb);
634
635 if (!IS_EPPING_PACKET(pHeader)) {
636 status = A_EINVAL;
637 break;
638 }
639
640 if (IS_EPING_PACKET_NO_DROP(pHeader)) {
641 htc_tag = AR6K_CONTROL_PKT_TAG;
642 }
643
644 length = sizeof(EPPING_HEADER) + pHeader->DataLength;
645
646 pPacket = AllocHTCStruct(pHcidevInfo);
647 if (NULL == pPacket) {
648 status = A_NO_MEMORY;
649 break;
650 }
651
652 SET_HTC_PACKET_INFO_TX(pPacket,
653 skb,
654 A_NETBUF_DATA(skb),
655 length,
656 HCI_ACL_TYPE, /* send every thing out as ACL */
657 htc_tag);
658
659 HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
660 pPacket = NULL;
661
662 } while (false);
663
664 return status;
665 }
666
667 void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig)
668 {
669 AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info;
670 AR3K_CONFIG_INFO *config = (AR3K_CONFIG_INFO *)ar3kconfig;
671
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;
678 }
679
680 #ifdef CONFIG_BLUEZ_HCI_BRIDGE
681 /*** BT Stack Entrypoints *******/
682
683 /*
684 * bt_open - open a handle to the device
685 */
686 static int bt_open(struct hci_dev *hdev)
687 {
688
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);
693 return 0;
694 }
695
696 /*
697 * bt_close - close handle to the device
698 */
699 static int bt_close(struct hci_dev *hdev)
700 {
701 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_close - enter\n"));
702 clear_bit(HCI_RUNNING, &hdev->flags);
703 return 0;
704 }
705
706 /*
707 * bt_send_frame - send data frames
708 */
709 static int bt_send_frame(struct sk_buff *skb)
710 {
711 struct hci_dev *hdev = (struct hci_dev *)skb->dev;
712 HCI_TRANSPORT_PACKET_TYPE type;
713 AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
714 HTC_PACKET *pPacket;
715 int status = 0;
716 struct sk_buff *txSkb = NULL;
717
718 if (!hdev) {
719 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n"));
720 return -ENODEV;
721 }
722
723 if (!test_bit(HCI_RUNNING, &hdev->flags)) {
724 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n"));
725 return -EBUSY;
726 }
727
728 pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data;
729 A_ASSERT(pHcidevInfo != NULL);
730
731 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type));
732 type = HCI_COMMAND_TYPE;
733
734 switch (bt_cb(skb)->pkt_type) {
735 case HCI_COMMAND_PKT:
736 type = HCI_COMMAND_TYPE;
737 hdev->stat.cmd_tx++;
738 break;
739
740 case HCI_ACLDATA_PKT:
741 type = HCI_ACL_TYPE;
742 hdev->stat.acl_tx++;
743 break;
744
745 case HCI_SCODATA_PKT:
746 /* we don't support SCO over the bridge */
747 kfree_skb(skb);
748 return 0;
749 default:
750 A_ASSERT(false);
751 kfree_skb(skb);
752 return 0;
753 }
754
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",
758 skb->len));
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));
763 }
764 AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
765 }
766
767 do {
768
769 txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom +
770 pHcidevInfo->HCIProps.TailRoom + skb->len,
771 GFP_ATOMIC);
772
773 if (txSkb == NULL) {
774 status = A_NO_MEMORY;
775 break;
776 }
777
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);
783
784 pPacket = AllocHTCStruct(pHcidevInfo);
785 if (NULL == pPacket) {
786 status = A_NO_MEMORY;
787 break;
788 }
789
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
793 */
794 SET_HTC_PACKET_INFO_TX(pPacket,
795 txSkb,
796 txSkb->data,
797 txSkb->len,
798 type,
799 AR6K_CONTROL_PKT_TAG); /* HCI packets cannot be dropped */
800
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",
803 type, txSkb->len));
804
805 status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false);
806 pPacket = NULL;
807 txSkb = NULL;
808
809 } while (false);
810
811 if (txSkb != NULL) {
812 kfree_skb(txSkb);
813 }
814
815 kfree_skb(skb);
816
817 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("-bt_send_frame \n"));
818 return 0;
819 }
820
821 /*
822 * bt_ioctl - ioctl processing
823 */
824 static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
825 {
826 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_ioctl - enter\n"));
827 return -ENOIOCTLCMD;
828 }
829
830 /*
831 * bt_flush - flush outstandingbpackets
832 */
833 static int bt_flush(struct hci_dev *hdev)
834 {
835 AR6K_HCI_BRIDGE_INFO *pHcidevInfo;
836
837 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n"));
838
839 pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data;
840
841 /* TODO??? */
842
843 return 0;
844 }
845
846
847 /*
848 * bt_destruct -
849 */
850 static void bt_destruct(struct hci_dev *hdev)
851 {
852 AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_destruct - enter\n"));
853 /* nothing to do here */
854 }
855
856 static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
857 {
858 int status = 0;
859 struct hci_dev *pHciDev = NULL;
860 HIF_DEVICE_OS_DEVICE_INFO osDevInfo;
861
862 if (!setupbtdev) {
863 return 0;
864 }
865
866 do {
867
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),
872 &osDevInfo);
873 #else
874 status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice,
875 HIF_DEVICE_GET_OS_DEVICE,
876 &osDevInfo,
877 sizeof(osDevInfo));
878 #endif
879
880 if (status) {
881 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n"));
882 break;
883 }
884
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;
890 break;
891 }
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;
906
907 } while (false);
908
909 if (status) {
910 bt_cleanup_hci(pHcidevInfo);
911 }
912
913 return status;
914 }
915
916 static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
917 {
918 int err;
919
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);
926 /* unregister */
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));
929 }
930 }
931
932 if (pHcidevInfo->pBtStackHCIDev != NULL) {
933 kfree(pHcidevInfo->pBtStackHCIDev);
934 pHcidevInfo->pBtStackHCIDev = NULL;
935 }
936 }
937
938 static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
939 {
940 int err;
941 int status = 0;
942
943 do {
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;
951 status = A_ERROR;
952 break;
953 }
954
955 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n"));
956
957 } while (false);
958
959 return status;
960 }
961
962 static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
963 HCI_TRANSPORT_PACKET_TYPE Type,
964 struct sk_buff *skb)
965 {
966 u8 btType;
967 int len;
968 bool success = false;
969 BT_HCI_EVENT_HEADER *pEvent;
970
971 do {
972
973 if (!test_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags)) {
974 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_indicate_recv - not running\n"));
975 break;
976 }
977
978 switch (Type) {
979 case HCI_ACL_TYPE:
980 btType = HCI_ACLDATA_PKT;
981 break;
982 case HCI_EVENT_TYPE:
983 btType = HCI_EVENT_PKT;
984 break;
985 default:
986 btType = 0;
987 A_ASSERT(false);
988 break;
989 }
990
991 if (0 == btType) {
992 break;
993 }
994
995 /* set the final type */
996 bt_cb(skb)->pkt_type = btType;
997 /* set dev */
998 skb->dev = (void *)pHcidevInfo->pBtStackHCIDev;
999 len = skb->len;
1000
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));
1006 }
1007 }
1008
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"));
1012 break;
1013 } else {
1014 AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV,
1015 ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType,len));
1016 }
1017
1018 success = true;
1019
1020 } while (false);
1021
1022 return success;
1023 }
1024
1025 static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length)
1026 {
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);
1030 if (NULL == skb) {
1031 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc bt sk_buff \n"));
1032 }
1033 return skb;
1034 }
1035
1036 static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb)
1037 {
1038 kfree_skb(skb);
1039 }
1040
1041 #else // { CONFIG_BLUEZ_HCI_BRIDGE
1042
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)
1045 {
1046 return 0;
1047 }
1048 static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
1049 {
1050
1051 }
1052 static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo)
1053 {
1054 A_ASSERT(false);
1055 return A_ERROR;
1056 }
1057
1058 static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo,
1059 HCI_TRANSPORT_PACKET_TYPE Type,
1060 struct sk_buff *skb)
1061 {
1062 A_ASSERT(false);
1063 return false;
1064 }
1065
1066 static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length)
1067 {
1068 A_ASSERT(false);
1069 return NULL;
1070 }
1071 static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb)
1072 {
1073 A_ASSERT(false);
1074 }
1075
1076 #endif // } CONFIG_BLUEZ_HCI_BRIDGE
1077
1078 #else // { ATH_AR6K_ENABLE_GMBOX
1079
1080 /* stubs when GMBOX support is not needed */
1081
1082 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1083 int ar6000_setup_hci(void *ar)
1084 #else
1085 int ar6000_setup_hci(AR_SOFTC_T *ar)
1086 #endif
1087 {
1088 return 0;
1089 }
1090
1091 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1092 void ar6000_cleanup_hci(void *ar)
1093 #else
1094 void ar6000_cleanup_hci(AR_SOFTC_T *ar)
1095 #endif
1096 {
1097 return;
1098 }
1099
1100 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
1101 void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig)
1102 {
1103 return;
1104 }
1105 #endif
1106
1107 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1108 int hci_test_send(void *ar, struct sk_buff *skb)
1109 #else
1110 int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb)
1111 #endif
1112 {
1113 return -EOPNOTSUPP;
1114 }
1115
1116 #endif // } ATH_AR6K_ENABLE_GMBOX
1117
1118
1119 #ifdef EXPORT_HCI_BRIDGE_INTERFACE
1120 static int __init
1121 hcibridge_init_module(void)
1122 {
1123 int status;
1124 HCI_TRANSPORT_CALLBACKS hciTransCallbacks;
1125
1126 hciTransCallbacks.setupTransport = ar6000_setup_hci;
1127 hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci;
1128
1129 status = ar6000_register_hci_transport(&hciTransCallbacks);
1130 if (status)
1131 return -ENODEV;
1132
1133 return 0;
1134 }
1135
1136 static void __exit
1137 hcibridge_cleanup_module(void)
1138 {
1139 }
1140
1141 module_init(hcibridge_init_module);
1142 module_exit(hcibridge_cleanup_module);
1143 MODULE_LICENSE("Dual BSD/GPL");
1144 #endif
This page took 0.080248 seconds and 5 git commands to generate.