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