Advertisement
Guest User

Untitled

a guest
Feb 5th, 2018
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 66.37 KB | None | 0 0
  1. diff --git a/arch/arm64/configs/even6737t_66_m0_sf_defconfig b/arch/arm64/configs/even6737t_66_m0_sf_defconfig
  2. index 734f100..cd3e97f 100644
  3. --- a/arch/arm64/configs/even6737t_66_m0_sf_defconfig
  4. +++ b/arch/arm64/configs/even6737t_66_m0_sf_defconfig
  5. @@ -1430,7 +1430,7 @@ CONFIG_MTK_COMBO_PLAT_PATH=""
  6.  # CONFIG_MTK_COMBO_COMM is not set
  7.  CONFIG_MTK_COMBO_BT=y
  8.  # CONFIG_MTK_COMBO_ANT is not set
  9. -# CONFIG_MTK_COMBO_BT_HCI is not set
  10. +CONFIG_MTK_COMBO_BT_HCI=y
  11.  CONFIG_MTK_COMBO_GPS=y
  12.  CONFIG_MTK_COMBO_WIFI=y
  13.  CONFIG_MTK_WAPI_SUPPORT=y
  14. diff --git a/drivers/misc/mediatek/connectivity/Kconfig b/drivers/misc/mediatek/connectivity/Kconfig
  15. index 878f3b6..80160d5 100644
  16. --- a/drivers/misc/mediatek/connectivity/Kconfig
  17. +++ b/drivers/misc/mediatek/connectivity/Kconfig
  18. @@ -194,6 +194,12 @@ config MTK_COMBO_BT
  19.     help
  20.       MTK BT /dev/stpbt driver for Bluedroid
  21.  
  22. +config MTK_COMBO_BT_HCI
  23. +   tristate "MediaTek Combo Chip BlueZ driver"
  24. +   depends on BT && MTK_COMBO
  25. +   help
  26. +     MTK BT driver for BlueZ (hci_stp.ko)
  27. +
  28.  config MTK_COMBO_ANT
  29.     tristate "MediaTek Combo Chip ANT driver"
  30.     depends on MTK_COMBO
  31. diff --git a/drivers/misc/mediatek/connectivity/Makefile b/drivers/misc/mediatek/connectivity/Makefile
  32. index fb6a7f1..0639c61 100644
  33. --- a/drivers/misc/mediatek/connectivity/Makefile
  34. +++ b/drivers/misc/mediatek/connectivity/Makefile
  35. @@ -16,6 +16,9 @@ endif
  36.  
  37.      obj-y += common/
  38.      obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/
  39. +#Use BT HCI driver
  40. +    obj-$(CONFIG_MTK_COMBO_BT_HCI) += drv_bt/
  41. +
  42.      obj-$(CONFIG_MTK_COMBO_GPS) += gps/
  43.      obj-n := dummy.o
  44.  
  45. diff --git a/drivers/misc/mediatek/connectivity/drv_bt/Makefile b/drivers/misc/mediatek/connectivity/drv_bt/Makefile
  46. new file mode 100644
  47. index 0000000..b876261
  48. --- /dev/null
  49. +++ b/drivers/misc/mediatek/connectivity/drv_bt/Makefile
  50. @@ -0,0 +1,43 @@
  51. +# Copyright Statement:
  52. +#
  53. +# This software/firmware and related documentation ("MediaTek Software") are
  54. +# protected under relevant copyright laws. The information contained herein
  55. +# is confidential and proprietary to MediaTek Inc. and/or its licensors.
  56. +# Without the prior written permission of MediaTek inc. and/or its licensors,
  57. +# any reproduction, modification, use or disclosure of MediaTek Software,
  58. +# and information contained herein, in whole or in part, shall be strictly prohibited.
  59. +#
  60. +# MediaTek Inc. (C) 2010. All rights reserved.
  61. +#
  62. +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  63. +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  64. +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  65. +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  66. +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  67. +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  68. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  69. +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  70. +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  71. +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  72. +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  73. +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  74. +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  75. +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  76. +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  77. +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  78. +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  79. +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  80. +#
  81. +# The following software/firmware and/or related documentation ("MediaTek Software")
  82. +# have been modified by MediaTek Inc. All revisions are subject to any receiver's
  83. +# applicable license agreements with MediaTek Inc.
  84. +
  85. +
  86. +#
  87. +# Makefile for the Linux Bluetooth HCI device drivers.
  88. +#
  89. +ccflags-y := -I$(src)/include -I$(src)/../common/include -I$(src)/../common/linux/include -I$(src)/../common/conn_soc/include -I$(src)/../common/conn_soc/linux/include -I$(src)/../common/common_detect -Wno-error
  90. +
  91. +obj-$(CONFIG_MTK_COMBO_BT_HCI) += hci_stp.o
  92. +hci_stp-objs   := linux/hci_stp.o
  93. +
  94. diff --git a/drivers/misc/mediatek/connectivity/drv_bt/include/bt_conf.h b/drivers/misc/mediatek/connectivity/drv_bt/include/bt_conf.h
  95. new file mode 100644
  96. index 0000000..248fcf1
  97. --- /dev/null
  98. +++ b/drivers/misc/mediatek/connectivity/drv_bt/include/bt_conf.h
  99. @@ -0,0 +1,45 @@
  100. +/* Copyright Statement:
  101. + *
  102. + * This software/firmware and related documentation ("MediaTek Software") are
  103. + * protected under relevant copyright laws. The information contained herein
  104. + * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  105. + * Without the prior written permission of MediaTek inc. and/or its licensors,
  106. + * any reproduction, modification, use or disclosure of MediaTek Software,
  107. + * and information contained herein, in whole or in part, shall be strictly prohibited.
  108. + *
  109. + * MediaTek Inc. (C) 2010. All rights reserved.
  110. + *
  111. + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  112. + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  113. + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  114. + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  115. + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  116. + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  117. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  118. + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  119. + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  120. + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  121. + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  122. + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  123. + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  124. + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  125. + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  126. + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  127. + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  128. + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  129. + *
  130. + * The following software/firmware and/or related documentation ("MediaTek Software")
  131. + * have been modified by MediaTek Inc. All revisions are subject to any receiver's
  132. + * applicable license agreements with MediaTek Inc.
  133. + */
  134. +
  135. +static struct btradio_conf_data sDefaultCfg =
  136. +{
  137. +    {0x00, 0x00, 0x46, 0x66, 0x20, 0x01},
  138. +    {0x60, 0x00},
  139. +    {0x23, 0x10, 0x00, 0x00},
  140. +    {0x06, 0x80, 0x00, 0x06, 0x03, 0x06},
  141. +    {0x03, 0x40, 0x1F, 0x40, 0x1F, 0x00, 0x04},
  142. +    {0x80, 0x00},
  143. +    {0xFF, 0xFF, 0xFF}
  144. +};
  145. \ No newline at end of file
  146. diff --git a/drivers/misc/mediatek/connectivity/drv_bt/include/hci_stp.h b/drivers/misc/mediatek/connectivity/drv_bt/include/hci_stp.h
  147. new file mode 100644
  148. index 0000000..cff49c1
  149. --- /dev/null
  150. +++ b/drivers/misc/mediatek/connectivity/drv_bt/include/hci_stp.h
  151. @@ -0,0 +1,172 @@
  152. +/* Copyright Statement:
  153. + *
  154. + * This software/firmware and related documentation ("MediaTek Software") are
  155. + * protected under relevant copyright laws. The information contained herein is
  156. + * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
  157. + * the prior written permission of MediaTek inc. and/or its licensors, any
  158. + * reproduction, modification, use or disclosure of MediaTek Software, and
  159. + * information contained herein, in whole or in part, shall be strictly
  160. + * prohibited.
  161. + *
  162. + * MediaTek Inc. (C) 2010. All rights reserved.
  163. + *
  164. + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  165. + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  166. + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  167. + * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
  168. + * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  169. + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  170. + * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
  171. + * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  172. + * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
  173. + * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  174. + * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  175. + * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
  176. + * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
  177. + * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  178. + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
  179. + * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
  180. + * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
  181. + * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  182. + * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  183. + *
  184. + * The following software/firmware and/or related documentation ("MediaTek
  185. + * Software") have been modified by MediaTek Inc. All revisions are subject to
  186. + * any receiver's applicable license agreements with MediaTek Inc.
  187. + */
  188. +
  189. +
  190. +#ifndef _HCI_STP_H
  191. +#define _HCI_STP_H
  192. +
  193. +#include <linux/module.h>
  194. +
  195. +#include <linux/kernel.h>
  196. +#include <linux/init.h>
  197. +#include <linux/types.h>
  198. +#include <linux/fcntl.h>
  199. +#include <linux/interrupt.h>
  200. +#include <linux/ptrace.h>
  201. +#include <linux/poll.h>
  202. +
  203. +#include <linux/slab.h>
  204. +#include <linux/tty.h>
  205. +#include <linux/errno.h>
  206. +#include <linux/string.h>
  207. +#include <linux/signal.h>
  208. +#include <linux/ioctl.h>
  209. +#include <linux/skbuff.h>
  210. +#include <linux/interrupt.h>
  211. +#include <linux/spinlock.h>
  212. +#include <linux/fs.h>
  213. +#include <asm/uaccess.h>
  214. +
  215. +/* debugging */
  216. +#include <linux/time.h>
  217. +#include <linux/delay.h>
  218. +
  219. +/* constant of kernel version */
  220. +#include <linux/version.h>
  221. +
  222. +/* kthread APIs */
  223. +#include <linux/kthread.h>
  224. +
  225. +#include <net/bluetooth/bluetooth.h>
  226. +#include <net/bluetooth/hci_core.h>
  227. +
  228. +
  229. +/*******************************************************************************
  230. +*                         C O M P I L E R   F L A G S
  231. +********************************************************************************
  232. +*/
  233. +
  234. +#define HCI_STP_TX_TASKLET (0) /* do tx in a tasklet context */
  235. +#define HCI_STP_TX_THRD (1) /* do tx in an init thread context */
  236. +/* select tx context */
  237. +#define HCI_STP_TX (HCI_STP_TX_THRD)
  238. +
  239. +
  240. +#if (HCI_STP_TX == HCI_STP_TX_TASKLET)
  241. +#define HCI_STP_TX_TASKLET_RWLOCK (0) /* use rwlock_t */
  242. +#define HCI_STP_TX_TASKLET_SPINLOCK (1) /* use spinlock_t */
  243. +/* select txq protection method */
  244. +#define HCI_STP_TX_TASKLET_LOCK (HCI_STP_TX_TASKLET_SPINLOCK)
  245. +#endif
  246. +
  247. +/* Flag to enable BD address auto-gen mechanism */
  248. +/* Auto-gen address is illegal, default disabled */
  249. +#define BD_ADDR_AUTOGEN (0)
  250. +
  251. +/*******************************************************************************
  252. +*                              C O N S T A N T S
  253. +********************************************************************************
  254. +*/
  255. +
  256. +/* HCI-STP flag bits */
  257. +#define HCI_STP_PROTO_SET (0)
  258. +/* HCI-STP flag TX states bits */
  259. +#define HCI_STP_SENDING (1)
  260. +#define HCI_STP_TX_WAKEUP (2)
  261. +
  262. +/* maximum delay required, shall also consider possible delay on a busy system. */
  263. +#define BT_CMD_DELAY_MS_COMM (100) /*(50)*/
  264. +#define BT_CMD_DELAY_MS_RESET (600) /*(500)*/
  265. +
  266. +#define BT_CMD_DELAY_SAFE_GUARD (20) /*(2)*/
  267. +
  268. +/* HCI-STP safer hci_reset handling */
  269. +#define HCI_STP_SAFE_RESET (1)
  270. +
  271. +/*******************************************************************************
  272. +*                             D A T A   T Y P E S
  273. +********************************************************************************
  274. +*/
  275. +struct hci_stp_init_cmd {
  276. +    unsigned char *hci_cmd;
  277. +    unsigned int cmdSz;
  278. +    unsigned char *hci_evt;
  279. +    unsigned int evtSz;
  280. +    char *str;
  281. +};
  282. +
  283. +struct hci_stp {
  284. +    struct hci_dev *hdev;
  285. +    unsigned long flags;
  286. +
  287. +    struct sk_buff_head txq; /* used to queue TX packets */
  288. +    unsigned long tx_state;
  289. +
  290. +    struct work_struct init_work;
  291. +    struct completion *p_init_comp;
  292. +    wait_queue_head_t *p_init_evt_wq;
  293. +    spinlock_t init_lock; /* protect init variables: comp and wq */
  294. +    unsigned int init_cmd_idx;
  295. +    int init_evt_rx_flag; /* init result of last sent cmd */
  296. +
  297. +#if HCI_STP_SAFE_RESET
  298. +    wait_queue_head_t reset_wq;
  299. +    atomic_t reset_count; /* !0: reset in progress */
  300. +#endif
  301. +    //void *priv; /* unused? */
  302. +    //struct sk_buff *tx_skb; /* unused? */
  303. +    //spinlock_t rx_lock; /* unused? */
  304. +};
  305. +
  306. +struct btradio_conf_data {
  307. +  unsigned char addr[6];
  308. +  unsigned char voice[2];
  309. +  unsigned char codec[4];
  310. +  unsigned char radio[6];
  311. +  unsigned char sleep[7];
  312. +  unsigned char feature[2];
  313. +  unsigned char tx_pwr_offset[3];
  314. +};
  315. +/*******************************************************************************
  316. +*                                 M A C R O S
  317. +********************************************************************************
  318. +*/
  319. +#define hci_stp_init_entry(c) \
  320. +  {.hci_cmd=c, .cmdSz=sizeof(c), .hci_evt=c##_evt, .evtSz=sizeof(c##_evt), .str=#c}
  321. +
  322. +#endif /* end of _HCI_STP_H */
  323. +
  324. diff --git a/drivers/misc/mediatek/connectivity/drv_bt/linux/hci_stp.c b/drivers/misc/mediatek/connectivity/drv_bt/linux/hci_stp.c
  325. new file mode 100644
  326. index 0000000..010599c
  327. --- /dev/null
  328. +++ b/drivers/misc/mediatek/connectivity/drv_bt/linux/hci_stp.c
  329. @@ -0,0 +1,1569 @@
  330. +/* Copyright Statement:
  331. + *
  332. + * This software/firmware and related documentation ("MediaTek Software") are
  333. + * protected under relevant copyright laws. The information contained herein is
  334. + * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
  335. + * the prior written permission of MediaTek inc. and/or its licensors, any
  336. + * reproduction, modification, use or disclosure of MediaTek Software, and
  337. + * information contained herein, in whole or in part, shall be strictly
  338. + * prohibited.
  339. + *
  340. + * MediaTek Inc. (C) 2010. All rights reserved.
  341. + *
  342. + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  343. + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  344. + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  345. + * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
  346. + * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  347. + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  348. + * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
  349. + * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  350. + * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
  351. + * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  352. + * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  353. + * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
  354. + * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
  355. + * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  356. + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
  357. + * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
  358. + * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
  359. + * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  360. + * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  361. + *
  362. + * The following software/firmware and/or related documentation ("MediaTek
  363. + * Software") have been modified by MediaTek Inc. All revisions are subject to
  364. + * any receiver's applicable license agreements with MediaTek Inc.
  365. + */
  366. +
  367. +
  368. +#include "hci_stp.h"
  369. +#include "bt_conf.h"
  370. +#include "stp_exp.h"
  371. +#include "wmt_exp.h"
  372. +
  373. +/*******************************************************************************
  374. +*                              C O N S T A N T S
  375. +********************************************************************************
  376. +*/
  377. +
  378. +/* Debugging Purpose */
  379. +#define PFX "[HCI-STP]"
  380. +#define BT_LOG_LOUD (4)
  381. +#define BT_LOG_DBG (3)
  382. +#define BT_LOG_INFO (2)
  383. +#define BT_LOG_WARN (1)
  384. +#define BT_LOG_ERR (0)
  385. +
  386. +#define VERSION "2.0"
  387. +
  388. +/* H4 receiver States */
  389. +#define H4_W4_PACKET_TYPE (0)
  390. +#define H4_W4_EVENT_HDR (1)
  391. +#define H4_W4_ACL_HDR (2)
  392. +#define H4_W4_SCO_HDR (3)
  393. +#define H4_W4_DATA (4)
  394. +
  395. +#define HCI_STP_TXQ_IN_BLZ (0)
  396. +/* access txq in BlueZ tx tasklet context */
  397. +#define HCI_STP_TXQ_IN_HCISTP (1)
  398. +/* access txq in HCI-STP context,  defined by compile flag: HCI_STP_TX */
  399. +
  400. +/*******************************************************************************
  401. +*                            P U B L I C   D A T A
  402. +********************************************************************************
  403. +*/
  404. +unsigned int gDbgLevelS = BT_LOG_INFO;
  405. +
  406. +/*******************************************************************************
  407. +*                           P R I V A T E   D A T A
  408. +********************************************************************************
  409. +*/
  410. +/* Allow one BT driver */
  411. +static struct hci_dev *hdev = NULL;
  412. +static int reset = 0;
  413. +
  414. +/* maybe struct hci_stp is a better place to put these data */
  415. +#if (HCI_STP_TX == HCI_STP_TX_TASKLET)
  416. +static struct tasklet_struct hci_tx_tasklet;
  417. +
  418. +#if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK)
  419. +static DEFINE_RWLOCK(hci_stp_txqlock);
  420. +
  421. +#elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK)
  422. +static spinlock_t hci_stp_txqlock;
  423. +
  424. +#endif
  425. +#endif
  426. +
  427. +#if (HCI_STP_TX == HCI_STP_TX_THRD)
  428. +static spinlock_t hci_stp_txqlock;
  429. +struct task_struct * hci_stp_tx_thrd = NULL;
  430. +wait_queue_head_t hci_stp_tx_thrd_wq;
  431. +#endif
  432. +
  433. +
  434. +#define CUSTOM_BT_CFG_FILE          "/data/BT.cfg"
  435. +#define INTERNAL_BT_CFG_FILE        "/data/bluetooth/BT.cfg"
  436. +
  437. +static bool fgetEFUSE = false;
  438. +
  439. +static unsigned char bt_get_bd_addr[4] =
  440. +    {0x01, 0x09, 0x10, 0x00};
  441. +static unsigned char bt_get_bd_addr_evt[] =
  442. +    {0x04, 0x0E, 0x0A, 0x01, 0x09, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  443. +static unsigned char bt_set_bd_addr[10] =
  444. +    {0x01, 0x1A, 0xFC, 0x06, 0x01, 0x20, 0x66, 0x46, 0x00, 0x00};
  445. +static unsigned char bt_set_bd_addr_evt[] =
  446. +    {0x04, 0x0E, 0x04, 0x01, 0x1A, 0xFC, 0x00};
  447. +static unsigned char bt_set_link_key_type[5]=
  448. +    {0x01, 0x1B, 0xFC, 0x01, 0x01};
  449. +static unsigned char bt_set_link_key_type_evt[] =
  450. +    {0x04, 0x0E, 0x04, 0x01, 0x1B, 0xFC, 0x00};
  451. +static unsigned char bt_set_unit_key[20] =
  452. +    {0x01, 0x75, 0xFC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  453. +static unsigned char bt_set_unit_key_evt[] =
  454. +    {0x04, 0x0E, 0x04, 0x01, 0x75, 0xFC, 0x00};
  455. +static unsigned char bt_set_encrypt[7] =
  456. +    {0x01, 0x76, 0xFC, 0x03, 0x00, 0x02, 0x10};
  457. +static unsigned char bt_set_encrypt_evt[] =
  458. +    {0x04, 0x0E, 0x04, 0x01, 0x76, 0xFC, 0x00};
  459. +static unsigned char bt_set_pin_code_type[5] =
  460. +    {0x01, 0x0A, 0x0C, 0x01, 0x00};
  461. +static unsigned char bt_set_pin_code_type_evt[] =
  462. +    {0x04, 0x0E, 0x04, 0x01, 0x0A, 0x0C, 0x00};
  463. +static unsigned char bt_set_voice[6] =
  464. +    {0x01, 0x26, 0x0C, 0x02, 0x60, 0x00};
  465. +static unsigned char bt_set_voice_evt[] =
  466. +    {0x04, 0x0E, 0x04, 0x01, 0x26, 0x0C, 0x00};
  467. +static unsigned char bt_set_codec[8] =
  468. +    {0x01, 0x72, 0xFC, 0x04, 0x23, 0x10, 0x00, 0x00};
  469. +static unsigned char bt_set_codec_evt[] =
  470. +    {0x04, 0x0E, 0x04, 0x01, 0x72, 0xFC, 0x00};
  471. +static unsigned char bt_set_radio[10] =
  472. +    {0x01, 0x79, 0xFC, 0x06, 0x06, 0x80, 0x00, 0x06, 0x03, 0x06};
  473. +static unsigned char bt_set_radio_evt[] =
  474. +    {0x04, 0x0E, 0x04, 0x01, 0x79, 0xFC, 0x00};
  475. +static unsigned char bt_set_tx_pwr_offset[7] =
  476. +    {0x01, 0x93, 0xFC, 0x03, 0xFF, 0xFF, 0xFF};
  477. +static unsigned char bt_set_tx_pwr_offset_evt[] =
  478. +    {0x04, 0x0E, 0x04, 0x01, 0x93, 0xFC, 0x00};
  479. +static unsigned char bt_set_sleep[11] =
  480. +    {0x01, 0x7A, 0xFC, 0x07, 0x03, 0x40, 0x1F, 0x40, 0x1F, 0x00, 0x04};
  481. +static unsigned char bt_set_sleep_evt[] =
  482. +    {0x04, 0x0E, 0x04, 0x01, 0x7A, 0xFC, 0x00};
  483. +static unsigned char bt_set_feature[6] =
  484. +    {0x01, 0x7D, 0xFC, 0x02, 0x80, 0x0};
  485. +static unsigned char bt_set_feature_evt[] =
  486. +    {0x04, 0x0E, 0x04, 0x01, 0x7D, 0xFC, 0x00};
  487. +static unsigned char bt_set_OSC[9] =
  488. +    {0x01, 0x7B, 0xFC, 0x05, 0x01, 0x01, 0x14, 0x0A, 0x05};
  489. +static unsigned char bt_set_OSC_evt[] =
  490. +    {0x04, 0x0E, 0x04, 0x01, 0x7B, 0xFC, 0x00};
  491. +static unsigned char bt_set_LPO[14] =
  492. +    {0x01, 0x7C, 0xFC, 0x0A, 0x01, 0xFA, 0x0A, 0x02, 0x00, 0xA6, 0x0E, 0x00, 0x40, 0x00};
  493. +static unsigned char bt_set_LPO_evt[] =
  494. +    {0x04, 0x0E, 0x04, 0x01, 0x7C, 0xFC, 0x00};
  495. +static unsigned char bt_set_legacy_PTA[14] =
  496. +    {0x01, 0x74, 0xFC, 0x0A, 0xC9, 0x8B, 0xBF, 0x00, 0x00, 0x52, 0x0E, 0x0E, 0x1F, 0x1B};
  497. +static unsigned char bt_set_legacy_PTA_evt[] =
  498. +    {0x04, 0x0E, 0x04, 0x01, 0x74, 0xFC, 0x00};
  499. +static unsigned char bt_set_BLE_PTA[9] =
  500. +    {0x01, 0xFC, 0xFC, 0x05, 0x16, 0x0E, 0x0E, 0x00, 0x07};
  501. +static unsigned char bt_set_BLE_PTA_evt[] =
  502. +    {0x04, 0x0E, 0x04, 0x01, 0xFC, 0xFC, 0x00};
  503. +static unsigned char bt_set_RF_desence[10] =
  504. +    {0x01, 0x20, 0xFC, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
  505. +static unsigned char bt_set_RF_desence_evt[] =
  506. +    {0x04, 0x0e, 0x04, 0x01, 0x20, 0xFC, 0x00};
  507. +static unsigned char bt_reset[4] =
  508. +    {0x01, 0x03, 0x0C, 0x0};
  509. +static unsigned char bt_reset_evt[] =
  510. +    {0x04, 0x0E, 0x04, 0x01, 0x03, 0x0C, 0x00};
  511. +static unsigned char bt_set_intern_PTA_1[19] =
  512. +    {0x01, 0xFB, 0xFC, 0x0F, 0x00, 0x01, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x02, 0x01};
  513. +static unsigned char bt_set_intern_PTA_1_evt[] =
  514. +    {0x04, 0x0E, 0x04, 0x01, 0xFB, 0xFC, 0x00};
  515. +static unsigned char bt_set_intern_PTA_2[11] =
  516. +    {0x01, 0xFB, 0xFC, 0x07, 0x01, 0x19, 0x19, 0x07, 0xD0, 0x00, 0x01};
  517. +static unsigned char bt_set_intern_PTA_2_evt[] =
  518. +    {0x04, 0x0E, 0x04, 0x01, 0xFB, 0xFC, 0x00};
  519. +static unsigned char bt_set_SLP_control_reg[12] =
  520. +    {0x01, 0xD0, 0xFC, 0x08, 0x74, 0x00, 0x01, 0x81, 0xE2, 0x29, 0x0, 0x0};
  521. +static unsigned char bt_set_SLP_control_reg_evt[] =
  522. +    {0x04, 0x0E, 0x04, 0x01, 0xD0, 0xFC, 0x00};
  523. +static unsigned char bt_set_SLP_LDOD_reg[12] =
  524. +    {0x01, 0xD0, 0xFC, 0x08, 0x1C, 0x00, 0x02, 0x81, 0x79, 0x08, 0x0, 0x0};
  525. +static unsigned char bt_set_SLP_LDOD_reg_evt[] =
  526. +    {0x04, 0x0E, 0x04, 0x01, 0xD0, 0xFC, 0x00};
  527. +static unsigned char bt_set_RF_reg_100[10] =
  528. +    {0x01, 0xB0, 0xFC, 0x06, 0x64, 0x01, 0x02, 0x00, 0x00, 0x00};
  529. +static unsigned char bt_set_RF_reg_100_evt[] =
  530. +    {0x04, 0x0E, 0x04, 0x01, 0xB0, 0xFC, 0x00};
  531. +
  532. +/* Do init commands in sequence, cmd and cmd##_evt */
  533. +static struct hci_stp_init_cmd init_table[] =
  534. +{
  535. +    hci_stp_init_entry(bt_get_bd_addr),
  536. +    hci_stp_init_entry(bt_set_bd_addr),
  537. +    hci_stp_init_entry(bt_set_link_key_type),
  538. +    hci_stp_init_entry(bt_set_unit_key),
  539. +    hci_stp_init_entry(bt_set_encrypt),
  540. +    hci_stp_init_entry(bt_set_pin_code_type),
  541. +    hci_stp_init_entry(bt_set_voice),
  542. +    hci_stp_init_entry(bt_set_codec),
  543. +    hci_stp_init_entry(bt_set_radio),
  544. +    hci_stp_init_entry(bt_set_tx_pwr_offset),
  545. +    hci_stp_init_entry(bt_set_sleep),
  546. +    hci_stp_init_entry(bt_set_feature),
  547. +    hci_stp_init_entry(bt_set_OSC),
  548. +    hci_stp_init_entry(bt_set_LPO),
  549. +    hci_stp_init_entry(bt_set_legacy_PTA),
  550. +    hci_stp_init_entry(bt_set_BLE_PTA),
  551. +    hci_stp_init_entry(bt_set_RF_desence),
  552. +    hci_stp_init_entry(bt_reset),
  553. +    hci_stp_init_entry(bt_set_intern_PTA_1),
  554. +    hci_stp_init_entry(bt_set_intern_PTA_2),
  555. +    hci_stp_init_entry(bt_set_SLP_control_reg),
  556. +    hci_stp_init_entry(bt_set_SLP_LDOD_reg),
  557. +    hci_stp_init_entry(bt_set_RF_reg_100),
  558. +};
  559. +
  560. +/*******************************************************************************
  561. +*                             D A T A   T Y P E S
  562. +********************************************************************************
  563. +*/
  564. +
  565. +/*******************************************************************************
  566. +*                                 M A C R O S
  567. +********************************************************************************
  568. +*/
  569. +
  570. +#define BT_LOUD_FUNC(fmt, arg...)   if(gDbgLevelS >= BT_LOG_LOUD){printk(PFX "[L]%s:"  fmt, __FUNCTION__ ,##arg);}
  571. +#define BT_DBG_FUNC(fmt, arg...)    if(gDbgLevelS >= BT_LOG_DBG){printk(PFX "[D]%s:"  fmt, __FUNCTION__ ,##arg);}
  572. +#define BT_INFO_FUNC(fmt, arg...)   if(gDbgLevelS >= BT_LOG_INFO){printk(PFX "[I]%s:"  fmt, __FUNCTION__ ,##arg);}
  573. +#define BT_WARN_FUNC(fmt, arg...)   if(gDbgLevelS >= BT_LOG_WARN){printk(PFX "[W]%s:"  fmt, __FUNCTION__ ,##arg);}
  574. +#define BT_ERR_FUNC(fmt, arg...)    if(gDbgLevelS >= BT_LOG_ERR){printk(PFX "[E]%s:"   fmt, __FUNCTION__ ,##arg);}
  575. +#define BT_TRC_FUNC(f)              if(gDbgLevelS >= BT_LOG_LOUD){printk(PFX "[T]%s:%d\n", __FUNCTION__, __LINE__);}
  576. +
  577. +#if HCI_STP_SAFE_RESET
  578. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
  579. +/* HCI_RESET bit definition in linux/include/net/bluetooth/hci.h since 2.6.39:
  580. +    http://lxr.free-electrons.com/source/include/net/bluetooth/hci.h?v=2.6.39;a=arm
  581. +*/
  582. +#define BT_GET_HDEV_RST_FG(hdev) (test_bit(HCI_RESET, &hdev->flags))
  583. +#else
  584. +#define BT_GET_HDEV_RST_FG(hdev) (0) /* no HCI_RESET bit available */
  585. +#endif
  586. +#endif
  587. +
  588. +/*******************************************************************************
  589. +*                  F U N C T I O N   D E C L A R A T I O N S
  590. +********************************************************************************
  591. +*/
  592. +/* Functions to be implemted by all HCI_STP_TX_* methods */
  593. +void hci_stp_tx_init (struct hci_stp *hu);
  594. +void hci_stp_tx_deinit (struct hci_stp *hu);
  595. +void hci_stp_txq_lock (unsigned int ctx);
  596. +void hci_stp_txq_unlock (unsigned int ctx);
  597. +void hci_stp_tx_kick (void);
  598. +
  599. +/* Functions to be implemented by all HCI_STP_INIT_* methods*/
  600. +static int hci_stp_dev_init (struct hci_stp *phu);
  601. +
  602. +#if (HCI_STP_TX == HCI_STP_TX_TASKLET)
  603. +static int hci_stp_tx_wakeup (struct hci_stp *hu);
  604. +static void hci_stp_tx_tasklet_func (unsigned long data);
  605. +#endif
  606. +
  607. +#if (HCI_STP_TX == HCI_STP_TX_THRD)
  608. +static int hci_stp_tx_thrd_func (void *pdata);
  609. +#endif
  610. +
  611. +/*******************************************************************************
  612. +*                              F U N C T I O N S
  613. +********************************************************************************
  614. +*/
  615. +
  616. +static ssize_t file_read(char *filename, char *buf, size_t len, loff_t *offset)
  617. +{
  618. +    struct file *fp;
  619. +    mm_segment_t old_fs;
  620. +    ssize_t retLen;
  621. +
  622. +    fp = filp_open(filename, O_RDONLY, 0);
  623. +    if (IS_ERR(fp)) {
  624. +        BT_WARN_FUNC("Failed to open %s!\n", filename);
  625. +        return -1;
  626. +    }
  627. +
  628. +    old_fs = get_fs();
  629. +    set_fs(KERNEL_DS);
  630. +
  631. +    if ((fp->f_op == NULL) || (fp->f_op->read == NULL)){
  632. +        BT_WARN_FUNC("File can not be read!\n");
  633. +        set_fs(old_fs);
  634. +        filp_close(fp, NULL);
  635. +        return -1;
  636. +    }
  637. +
  638. +    retLen = fp->f_op->read(fp, buf, len, offset);
  639. +
  640. +    set_fs(old_fs);
  641. +    filp_close(fp, NULL);
  642. +
  643. +    return retLen;
  644. +}
  645. +
  646. +static ssize_t file_write(char *filename, char *buf, size_t len, loff_t *offset)
  647. +{
  648. +    struct file *fp;
  649. +    mm_segment_t old_fs;
  650. +    ssize_t retLen;
  651. +
  652. +    fp = filp_open(filename, O_WRONLY | O_CREAT, 0644);
  653. +    if (IS_ERR(fp)) {
  654. +        BT_WARN_FUNC("Failed to open %s!\n", filename);
  655. +        return -1;
  656. +    }
  657. +
  658. +    old_fs = get_fs();
  659. +    set_fs(KERNEL_DS);
  660. +
  661. +    if ((fp->f_op == NULL) || (fp->f_op->write == NULL)){
  662. +        BT_WARN_FUNC("File can not be write!\n");
  663. +        set_fs(old_fs);
  664. +        filp_close(fp, NULL);
  665. +        return -1;
  666. +    }
  667. +
  668. +    retLen = fp->f_op->write(fp, buf, len, offset);
  669. +
  670. +    set_fs(old_fs);
  671. +    filp_close(fp, NULL);
  672. +
  673. +    return retLen;
  674. +}
  675. +
  676. +int load_custom_bt_conf(struct btradio_conf_data *cfg)
  677. +{
  678. +   /*
  679. +    This method depends on customer's platform configuration data
  680. +    store machenism.
  681. +    Customer may use NVRAM, data file, or other patterns.
  682. +    Here RECOMMEND and GIVE AN EXAMPLE to push configuration data
  683. +    under /data/BT.cfg
  684. +    */
  685. +
  686. +    struct btradio_conf_data temp;
  687. +    loff_t pos = 0;
  688. +    ssize_t retLen;
  689. +
  690. +    retLen = file_read(CUSTOM_BT_CFG_FILE,
  691. +                       (char*)&temp,
  692. +                       sizeof(temp),
  693. +                       &pos);
  694. +
  695. +    if (retLen < 0)
  696. +        return -1;
  697. +
  698. +    if(retLen < sizeof(temp)){
  699. +        BT_ERR_FUNC("File read error len: %zu\n", retLen);
  700. +        return -1;
  701. +    }
  702. +    else{
  703. +        memcpy(cfg, &temp, retLen);
  704. +        return 0;
  705. +    }
  706. +}
  707. +
  708. +int load_internal_bt_conf(struct btradio_conf_data *cfg)
  709. +{
  710. +    struct btradio_conf_data temp;
  711. +    loff_t pos = 0;
  712. +    ssize_t retLen;
  713. +    ssize_t written;
  714. +
  715. +    retLen = file_read(INTERNAL_BT_CFG_FILE,
  716. +                       (char*)&temp,
  717. +                       sizeof(temp),
  718. +                       &pos);
  719. +
  720. +    if (retLen < 0){
  721. +        BT_INFO_FUNC("No internal BT config, generate from default value\n");
  722. +        memcpy(&temp, &sDefaultCfg, sizeof(struct btradio_conf_data));
  723. +
  724. +        // Generate internal BT config file
  725. +        pos = 0;
  726. +        written = file_write(INTERNAL_BT_CFG_FILE,
  727. +                             (char*)&temp,
  728. +                             sizeof(temp),
  729. +                             &pos);
  730. +        if (written < 0){
  731. +            BT_ERR_FUNC("Try to create internal BT config, error\n");
  732. +            return -1;
  733. +        }
  734. +        else if(written < sizeof(temp)){
  735. +            BT_ERR_FUNC("File write error len: %zu\n", written);
  736. +        }
  737. +        else{
  738. +            BT_INFO_FUNC("Internal BT config generated\n");
  739. +        }
  740. +
  741. +        memcpy(cfg, &temp, sizeof(temp));
  742. +        return 0;
  743. +    }
  744. +    else if(retLen < sizeof(temp)){
  745. +        BT_ERR_FUNC("File read error len: %zu\n", retLen);
  746. +    }
  747. +
  748. +    memcpy(cfg, &temp, retLen);
  749. +    return 0;
  750. +}
  751. +
  752. +
  753. +static inline void hci_stp_tx_skb_comp (struct hci_stp *hu, struct sk_buff *skb)
  754. +{
  755. +    struct hci_dev *hdev;
  756. +    int pkt_type;
  757. +
  758. +
  759. +    hdev = hu->hdev;
  760. +    hdev->stat.byte_tx += skb->len;
  761. +
  762. +    pkt_type = bt_cb(skb)->pkt_type;
  763. +    /* Update HCI stat counters */
  764. +    switch (pkt_type) {
  765. +       case HCI_COMMAND_PKT:
  766. +            hdev->stat.cmd_tx++;
  767. +            break;
  768. +
  769. +       case HCI_ACLDATA_PKT:
  770. +            hdev->stat.acl_tx++;
  771. +            break;
  772. +
  773. +       case HCI_SCODATA_PKT:
  774. +            hdev->stat.cmd_tx++;
  775. +            break;
  776. +    }
  777. +}
  778. +
  779. +#if (HCI_STP_TX == HCI_STP_TX_TASKLET)
  780. +void hci_stp_tx_init (struct hci_stp *hu)
  781. +{
  782. +    tasklet_init(&hci_tx_tasklet, hci_stp_tx_tasklet_func, (unsigned long)hu);
  783. +
  784. +    #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK)
  785. +    rwlock_init(&hci_stp_txqlock);
  786. +    #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK)
  787. +    spin_lock_init(&hci_stp_txqlock);
  788. +    #endif
  789. +}
  790. +
  791. +void hci_stp_tx_deinit (struct hci_stp *hu)
  792. +{
  793. +    tasklet_kill(&hci_tx_tasklet);
  794. +
  795. +    return;
  796. +}
  797. +
  798. +void hci_stp_txq_lock (unsigned int ctx)
  799. +{
  800. +    if (ctx == HCI_STP_TXQ_IN_BLZ) {
  801. +        /* lock txq in BlueZ tx tasklet context */
  802. +    #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK)
  803. +        write_lock_bh(&hci_stp_txqlock);
  804. +    #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK)
  805. +        spin_lock_bh(&hci_stp_txqlock);
  806. +    #else
  807. +    #error "HCI_STP_TX_TASKLET_LOCK"
  808. +    #endif
  809. +    }
  810. +    else {
  811. +        /* lock txq in HCI-STP context(defined by compile flag: HCI_STP_TX) */
  812. +    #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK)
  813. +        write_lock_bh(&hci_stp_txqlock);
  814. +    #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK)
  815. +        spin_lock_bh(&hci_stp_txqlock);
  816. +    #else
  817. +    #error "HCI_STP_TX_TASKLET_LOCK"
  818. +    #endif
  819. +    }
  820. +}
  821. +
  822. +void hci_stp_txq_unlock (unsigned int ctx)
  823. +{
  824. +    if (ctx == HCI_STP_TXQ_IN_BLZ) {
  825. +        /* lock txq in BlueZ tx tasklet context with hci_stp_tx */
  826. +    #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK)
  827. +        write_unlock_bh(&hci_stp_txqlock);
  828. +    #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK)
  829. +        spin_unlock_bh(&hci_stp_txqlock);
  830. +    #else
  831. +    #error "HCI_STP_TX_TASKLET_LOCK"
  832. +    #endif
  833. +    }
  834. +    else {
  835. +        /* lock txq in HCI-STP context(defined by compile flag: HCI_STP_TX) */
  836. +    #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK)
  837. +        write_unlock_bh(&hci_stp_txqlock);
  838. +    #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK)
  839. +        spin_unlock_bh(&hci_stp_txqlock);
  840. +    #else
  841. +    #error "HCI_STP_TX_TASKLET_LOCK"
  842. +    #endif
  843. +    }
  844. +}
  845. +
  846. +void hci_stp_tx_kick (void)
  847. +{
  848. +    tasklet_schedule(&hci_tx_tasklet);
  849. +}
  850. +
  851. +static void hci_stp_tx_tasklet_func(unsigned long data) {
  852. +
  853. +    struct hci_stp *hu = (struct hci_stp *)data;
  854. +
  855. +    /* sanity check to see if status is still correct? */
  856. +    if (unlikely(hdev == NULL)) {
  857. +        BT_ERR_FUNC("Null hdev!\n");
  858. +        BUG_ON(hdev == NULL);
  859. +        return;
  860. +    }
  861. +
  862. +    if (unlikely(hu != hdev->driver_data)) {
  863. +        BT_ERR_FUNC("hu(0x%p) != hdev->driver_data(0x%p)\n",
  864. +            hu, hdev->driver_data);
  865. +        BUG_ON(hu != hdev->driver_data);
  866. +        return;
  867. +    }
  868. +
  869. +    //read_lock(&hci_stp_txq_lock);
  870. +    hci_stp_txq_lock(HCI_STP_TXQ_IN_HCISTP);
  871. +
  872. +    hci_stp_tx_wakeup(hu);
  873. +
  874. +    //read_unlock(&hci_stp_txq_lock);
  875. +    hci_stp_txq_unlock(HCI_STP_TXQ_IN_HCISTP);
  876. +}
  877. +
  878. +/* George: HCI_STP_SENDING and HCI_STP_TX_WAKEUP flags in this function seem
  879. +* to be redundant.
  880. +*/
  881. +static int hci_stp_tx_wakeup(struct hci_stp *hu)
  882. +{
  883. +//    struct hci_dev *hdev = hu->hdev;
  884. +    struct sk_buff *skb;
  885. +    int j = 0;
  886. +
  887. +    BT_TRC_FUNC();
  888. +
  889. +    if (test_and_set_bit(HCI_STP_SENDING, &hu->tx_state)) {
  890. +        set_bit(HCI_STP_TX_WAKEUP, &hu->tx_state);
  891. +        printk("[BT] enqueue and return\n");
  892. +        return 0;
  893. +    }
  894. +
  895. +    BT_DBG_FUNC("hci_stp_tx_wakeup %d\n", __LINE__);
  896. +
  897. +restart:
  898. +    clear_bit(HCI_STP_TX_WAKEUP, &hu->tx_state);
  899. +
  900. +    while ((skb = skb_dequeue(&hu->txq))) {
  901. +        int len;
  902. +        BT_DBG_FUNC("dqueue times = %d\n", ++j);
  903. +
  904. +        /* hci reset cmd check */
  905. +#if HCI_STP_SAFE_RESET
  906. +        if (unlikely(skb->len == ARRAY_SIZE(bt_reset))) {
  907. +            if (unlikely(!memcmp(bt_reset, skb->data, ARRAY_SIZE(bt_reset)))) {
  908. +                atomic_inc(&hu->reset_count);
  909. +                BT_DBG_FUNC("hci reset cmd,f(%d),c(%d)\n",
  910. +                    BT_GET_HDEV_RST_FG(hdev),
  911. +                    atomic_read(&hu->reset_count));
  912. +            }
  913. +        }
  914. +#endif
  915. +
  916. +        if ((len = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX)) == 0 ) {
  917. +            /* can not send */
  918. +            BT_ERR_FUNC("mtk_wcn_stp_send_data can not send\n");
  919. +            BT_ERR_FUNC("Error %s %d\n", __FUNCTION__, __LINE__);
  920. +
  921. +            skb_queue_head(&hu->txq, skb);//Put back to queue head
  922. +            goto END;
  923. +        }
  924. +
  925. +        //hdev->stat.byte_tx += len; // moved into hci_stp_tx_skb_comp()
  926. +        //hci_stp_tx_skb_comp(hu, bt_cb(skb)->pkt_type);
  927. +        hci_stp_tx_skb_comp(hu, skb);
  928. +        kfree_skb(skb);
  929. +    }
  930. +
  931. +END:
  932. +    if (test_bit(HCI_STP_TX_WAKEUP, &hu->tx_state))
  933. +          goto restart;
  934. +
  935. +    clear_bit(HCI_STP_SENDING, &hu->tx_state);
  936. +
  937. +    return 0;
  938. +}
  939. +
  940. +
  941. +#elif (HCI_STP_TX == HCI_STP_TX_THRD)
  942. +
  943. +void hci_stp_tx_init (struct hci_stp *hu)
  944. +{
  945. +    spin_lock_init(&hci_stp_txqlock);
  946. +    init_waitqueue_head(&hci_stp_tx_thrd_wq);
  947. +
  948. +    hci_stp_tx_thrd = kthread_create(hci_stp_tx_thrd_func, (void *)hu, "hci_stpd");
  949. +    if (NULL == hci_stp_tx_thrd) {
  950. +        BT_ERR_FUNC("kthread_create hci_stpd fail!\n");
  951. +    }
  952. +    wake_up_process(hci_stp_tx_thrd);
  953. +
  954. +    return;
  955. +}
  956. +
  957. +void hci_stp_tx_deinit (struct hci_stp *hu)
  958. +{
  959. +    kthread_stop(hci_stp_tx_thrd);
  960. +    hci_stp_tx_thrd = NULL;
  961. +
  962. +    return;
  963. +}
  964. +
  965. +void hci_stp_txq_lock (unsigned int ctx)
  966. +{
  967. +    if (ctx == HCI_STP_TXQ_IN_BLZ) {
  968. +        /* lock txq in BlueZ tx tasklet context */
  969. +        spin_lock(&hci_stp_txqlock);
  970. +    }
  971. +    else {
  972. +        /* lock txq in HCI-STP context(defined by compile flag: HCI_STP_TX) */
  973. +        spin_lock_bh(&hci_stp_txqlock);
  974. +    }
  975. +}
  976. +
  977. +void hci_stp_txq_unlock (unsigned int ctx)
  978. +{
  979. +    if (ctx == HCI_STP_TXQ_IN_BLZ) {
  980. +        spin_unlock(&hci_stp_txqlock);
  981. +    }
  982. +    else {
  983. +        /* lock txq in HCI-STP context(defined by compile flag: HCI_STP_TX) */
  984. +        spin_unlock_bh(&hci_stp_txqlock);
  985. +    }
  986. +}
  987. +
  988. +static int
  989. +hci_stp_tx_thrd_func (void *pdata)
  990. +{
  991. +    struct hci_stp *hu;
  992. +    struct hci_dev *hdev;
  993. +    struct sk_buff *skb;
  994. +    int len;
  995. +
  996. +    hu = (struct hci_stp *)pdata;
  997. +    hdev = hu->hdev;
  998. +
  999. +    /* sanity check to see if status is still correct? */
  1000. +    if (unlikely(hdev == NULL)) {
  1001. +        BT_ERR_FUNC("Null hdev!\n");
  1002. +        BUG_ON(hdev == NULL);
  1003. +        return -1;
  1004. +    }
  1005. +
  1006. +    if (unlikely(hu != hdev->driver_data)) {
  1007. +        BT_ERR_FUNC("hu(0x%p) != hdev->driver_data(0x%p)\n",
  1008. +            hu, hdev->driver_data);
  1009. +        BUG_ON(hu != hdev->driver_data);
  1010. +        return -1;
  1011. +    }
  1012. +
  1013. +    for (;;) {
  1014. +        smp_rmb(); /* sync shared data */
  1015. +
  1016. +        wait_event_interruptible(hci_stp_tx_thrd_wq,
  1017. +            (!skb_queue_empty(&hu->txq) || kthread_should_stop()));
  1018. +
  1019. +        if (unlikely(kthread_should_stop())) {
  1020. +            BT_DBG_FUNC("hci_stpd thread should stop now... \n");
  1021. +            break;
  1022. +        }
  1023. +
  1024. +        hci_stp_txq_lock(HCI_STP_TXQ_IN_HCISTP);
  1025. +        while ((skb = skb_dequeue(&hu->txq))) {
  1026. +            /* protect txq only */
  1027. +            hci_stp_txq_unlock(HCI_STP_TXQ_IN_HCISTP);
  1028. +
  1029. +            /* hci reset cmd check */
  1030. +    #if HCI_STP_SAFE_RESET
  1031. +            if (unlikely(skb->len == ARRAY_SIZE(bt_reset))) {
  1032. +                if (unlikely(!memcmp(bt_reset, skb->data, ARRAY_SIZE(bt_reset)))) {
  1033. +                    atomic_inc(&hu->reset_count);
  1034. +                    BT_DBG_FUNC("hci reset cmd,f(%d),c(%d)\n",
  1035. +                        BT_GET_HDEV_RST_FG(hdev),
  1036. +                        atomic_read(&hu->reset_count));
  1037. +                }
  1038. +            }
  1039. +    #endif
  1040. +
  1041. +            len = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX);
  1042. +            if (unlikely(len != skb->len)) {
  1043. +                /* can not send */
  1044. +                BT_ERR_FUNC("mtk_wcn_stp_send_data fail, enqueue again!(%d, %d)\n",
  1045. +                    len, skb->len);
  1046. +
  1047. +                hci_stp_txq_lock(HCI_STP_TXQ_IN_HCISTP);
  1048. +                skb_queue_head(&hu->txq, skb);//Put back to queue head
  1049. +                /* do hci_stp_txq_unlock outside while loop */
  1050. +                break;
  1051. +            }
  1052. +            //hdev->stat.byte_tx += len; // moved into hci_stp_tx_skb_comp()
  1053. +            hci_stp_tx_skb_comp(hu, skb);
  1054. +            kfree_skb(skb);
  1055. +
  1056. +            hci_stp_txq_lock(HCI_STP_TXQ_IN_HCISTP);
  1057. +        }
  1058. +        hci_stp_txq_unlock(HCI_STP_TXQ_IN_HCISTP);
  1059. +
  1060. +        /* back to wait */
  1061. +    }
  1062. +
  1063. +    BT_INFO_FUNC("tx thread stop!\n");
  1064. +    return 0;
  1065. +}
  1066. +
  1067. +void hci_stp_tx_kick (void)
  1068. +{
  1069. +    smp_wmb();
  1070. +    wake_up_interruptible(&hci_stp_tx_thrd_wq);
  1071. +}
  1072. +
  1073. +#else
  1074. +#error "Not implemented HCI_STP_TX"
  1075. +#endif
  1076. +
  1077. +
  1078. +void hci_stp_dev_init_rx_cb (const UINT8 *data, INT32 count)
  1079. +{
  1080. +    struct hci_stp *hu;
  1081. +    unsigned int idx;
  1082. +
  1083. +    if (unlikely(!hdev)) {
  1084. +        BT_ERR_FUNC("null hdev!\n");
  1085. +        return;
  1086. +    }
  1087. +    if (unlikely(!hdev->driver_data)) {
  1088. +        BT_ERR_FUNC("null hdev->driver_data!\n");
  1089. +        return;
  1090. +    }
  1091. +
  1092. +    /* get hci_stp from global variable */
  1093. +    hu = (struct hci_stp *)hdev->driver_data;
  1094. +    idx = hu->init_cmd_idx;
  1095. +
  1096. +    if (unlikely(count != init_table[idx].evtSz)){
  1097. +        hu->init_evt_rx_flag = -1; /* size mismatch */
  1098. +    }
  1099. +    else if (unlikely(memcmp(data, init_table[idx].hci_evt, 7))){
  1100. +        hu->init_evt_rx_flag = -2; /* content mismatch */
  1101. +    }
  1102. +    else{
  1103. +        hu->init_evt_rx_flag = 1; /* ok */
  1104. +        BT_DBG_FUNC("EVT(%d) len(%d) ok\n", idx, count);
  1105. +        if (idx == 0) {
  1106. +            /* store the returned eFUSE address */
  1107. +            memcpy(&bt_get_bd_addr_evt[7], &data[7], 6);
  1108. +        }
  1109. +    }
  1110. +
  1111. +    if (unlikely(1 != hu->init_evt_rx_flag)) {
  1112. +        int i;
  1113. +        BT_WARN_FUNC("EVT(%d) len(%d) buf:[", idx, count);
  1114. +        for (i = 0; i < count; ++i) {
  1115. +            printk("0x%02x ", data[i]);
  1116. +        }
  1117. +        printk("]\n");
  1118. +        BT_WARN_FUNC("EVT(%d) exp(%d) buf:[", idx, init_table[idx].evtSz);
  1119. +        for (i = 0; i < count; ++i) {
  1120. +            printk("0x%02x ", init_table[idx].hci_evt[i]);
  1121. +        }
  1122. +        printk("]\n");
  1123. +
  1124. +    }
  1125. +
  1126. +    smp_wmb(); /* sync shared data */
  1127. +
  1128. +    spin_lock(&hu->init_lock);
  1129. +    if (likely(hu->p_init_evt_wq)) {
  1130. +        wake_up(hu->p_init_evt_wq); /* wake up dev_init_work */
  1131. +    }
  1132. +    else {
  1133. +        int i;
  1134. +        BT_WARN_FUNC("late EVT(%d) len(%d) buf:[", idx, count);
  1135. +        for (i = 0; i < count; ++i) {
  1136. +            printk("0x%02x ", data[i]);
  1137. +        }
  1138. +        printk("]\n");
  1139. +        BT_WARN_FUNC("Please check if uart rx data is returned or processed in time for BT init!\n");
  1140. +        BT_WARN_FUNC("Possibly caused by a very busy system, or stp_uart rx priority too low...\n");
  1141. +        BT_WARN_FUNC("Check which one is the real case and try to raise stp_uart rx priority.\n");
  1142. +    }
  1143. +    spin_unlock(&hu->init_lock);
  1144. +}
  1145. +
  1146. +static void hci_stp_dev_init_work (struct work_struct *work)
  1147. +{
  1148. +    struct hci_stp *phu;
  1149. +    unsigned int idx;
  1150. +    long ret, to;
  1151. +
  1152. +    struct btradio_conf_data cfg = {
  1153. +        {0x00, 0x00, 0x46, 0x66, 0x20, 0x01},
  1154. +        {0x60, 0x00},
  1155. +        {0x23, 0x10, 0x00, 0x00},
  1156. +        {0x06, 0x80, 0x00, 0x06, 0x03, 0x06},
  1157. +        {0x03, 0x40, 0x1F, 0x40, 0x1F, 0x00, 0x04},
  1158. +        {0x80, 0x00},
  1159. +        {0xFF, 0xFF, 0xFF}};
  1160. +
  1161. +    /* get client's information */
  1162. +    phu = container_of(work, struct hci_stp, init_work);
  1163. +
  1164. +    if (load_custom_bt_conf(&cfg) < 0){
  1165. +        BT_INFO_FUNC("No custom BT config\n");
  1166. +
  1167. +        if (load_internal_bt_conf(&cfg) < 0){
  1168. +            BT_ERR_FUNC("Load internal BT config failed!\n");
  1169. +        }
  1170. +        else{
  1171. +            BT_INFO_FUNC("Load internal BT config success\n");
  1172. +
  1173. +            if (0 == memcmp(cfg.addr, sDefaultCfg.addr, 6)){
  1174. +                /* BD address default value, want to retrieve module eFUSE */
  1175. +                fgetEFUSE = true;
  1176. +                /* retrieve eFUSE address in init command loop */
  1177. +            }
  1178. +        }
  1179. +    }
  1180. +    else{
  1181. +        BT_INFO_FUNC("Load custom BT config success\n");
  1182. +    }
  1183. +
  1184. +    BT_DBG_FUNC("Read BT config data:\n");
  1185. +    BT_DBG_FUNC("[BD address %02x-%02x-%02x-%02x-%02x-%02x]\n",
  1186. +        cfg.addr[0], cfg.addr[1], cfg.addr[2], cfg.addr[3], cfg.addr[4], cfg.addr[5]);
  1187. +    BT_DBG_FUNC("[voice %02x %02x][codec %02x %02x %02x %02x]\n",
  1188. +        cfg.voice[0], cfg.voice[1], cfg.codec[0], cfg.codec[1], cfg.codec[2], cfg.codec[3]);
  1189. +    BT_DBG_FUNC("[radio %02x %02x %02x %02x %02x %02x]\n",
  1190. +        cfg.radio[0], cfg.radio[1], cfg.radio[2], cfg.radio[3], cfg.radio[4], cfg.radio[5]);
  1191. +    BT_DBG_FUNC("[sleep %02x %02x %02x %02x %02x %02x %02x]\n",
  1192. +        cfg.sleep[0], cfg.sleep[1], cfg.sleep[2], cfg.sleep[3], cfg.sleep[4], cfg.sleep[5], cfg.sleep[6]);
  1193. +    BT_DBG_FUNC("[feature %02x %02x]\n",
  1194. +        cfg.feature[0], cfg.feature[1]);
  1195. +    BT_DBG_FUNC("[tx power offset %02x %02x %02x]\n",
  1196. +        cfg.tx_pwr_offset[0], cfg.tx_pwr_offset[1], cfg.tx_pwr_offset[2]);
  1197. +
  1198. +    bt_set_bd_addr[4] = cfg.addr[5];
  1199. +    bt_set_bd_addr[5] = cfg.addr[4];
  1200. +    bt_set_bd_addr[6] = cfg.addr[3];
  1201. +    bt_set_bd_addr[7] = cfg.addr[2];
  1202. +    bt_set_bd_addr[8] = cfg.addr[1];
  1203. +    bt_set_bd_addr[9] = cfg.addr[0];
  1204. +
  1205. +    memcpy(&bt_set_voice[4], cfg.voice, 2);
  1206. +    memcpy(&bt_set_codec[4], cfg.codec, 4);
  1207. +    memcpy(&bt_set_radio[4], cfg.radio, 6);
  1208. +    memcpy(&bt_set_tx_pwr_offset[4], cfg.tx_pwr_offset, 3);
  1209. +    memcpy(&bt_set_sleep[4], cfg.sleep, 7);
  1210. +    memcpy(&bt_set_feature[4], cfg.feature, 2);
  1211. +
  1212. +    /*
  1213. +     * INIT command loop starts
  1214. +     */
  1215. +    if (fgetEFUSE == true)
  1216. +        idx = 0;
  1217. +    else // skip bt_get_bd_addr
  1218. +        idx = 1;
  1219. +
  1220. +    for (; idx < ARRAY_SIZE(init_table); ++idx) {
  1221. +        phu->init_cmd_idx = idx;
  1222. +        phu->init_evt_rx_flag = 0;
  1223. +        to = (init_table[idx].hci_cmd == bt_reset) ? BT_CMD_DELAY_MS_RESET : BT_CMD_DELAY_MS_COMM;
  1224. +        /* safe waiting time in case running on a busy system */
  1225. +        to = msecs_to_jiffies(to * BT_CMD_DELAY_SAFE_GUARD);
  1226. +
  1227. +        BT_DBG_FUNC("CMD(%d) (%s) t/o(%ld))\n", idx, init_table[idx].str, to);
  1228. +        smp_wmb(); /* sync shared data */
  1229. +
  1230. +        /* Send hci command */
  1231. +        mtk_wcn_stp_send_data(init_table[idx].hci_cmd, init_table[idx].cmdSz, BT_TASK_INDX);
  1232. +        /* Wait rx hci event */
  1233. +        /* no need to lock init_lock here for wq, for that it will be freed
  1234. +         * only after we call complete(phu->p_init_comp); in this function.
  1235. +         */
  1236. +        ret = wait_event_timeout((*phu->p_init_evt_wq), phu->init_evt_rx_flag != 0, to);
  1237. +
  1238. +        /* Check result */
  1239. +        if (likely(1 == phu->init_evt_rx_flag)) {
  1240. +            if (idx == 0)
  1241. +            { // bt_get_bd_addr event handler
  1242. +//WATWATWATWATWATWAT
  1243. +//                unsigned long randNum;
  1244. +                loff_t pos = 0;
  1245. +                ssize_t written;
  1246. +
  1247. +                BT_DBG_FUNC("Retrieve eFUSE address %02x-%02x-%02x-%02x-%02x-%02x\n",
  1248. +                    bt_get_bd_addr_evt[12], bt_get_bd_addr_evt[11], bt_get_bd_addr_evt[10], bt_get_bd_addr_evt[9], bt_get_bd_addr_evt[8], bt_get_bd_addr_evt[7]);
  1249. +
  1250. +                cfg.addr[0] = bt_get_bd_addr_evt[12];
  1251. +                cfg.addr[1] = bt_get_bd_addr_evt[11];
  1252. +                cfg.addr[2] = bt_get_bd_addr_evt[10];
  1253. +                cfg.addr[3] = bt_get_bd_addr_evt[9];
  1254. +                cfg.addr[4] = bt_get_bd_addr_evt[8];
  1255. +                cfg.addr[5] = bt_get_bd_addr_evt[7];
  1256. +
  1257. +                if (0 == memcmp(cfg.addr, sDefaultCfg.addr, 6)){
  1258. +                #if BD_ADDR_AUTOGEN
  1259. +                    /* eFUSE address default value, enable auto-gen */
  1260. +                    BT_DBG_FUNC("eFUSE address default value, enable auto-gen!\n");
  1261. +                    get_random_bytes(&randNum, sizeof(unsigned long));
  1262. +                    BT_DBG_FUNC("Get random number: %lu\n", randNum);
  1263. +
  1264. +                    bt_get_bd_addr_evt[12] = (((randNum>>24 | randNum>>16) & (0xFE)) | (0x02));
  1265. +                    bt_get_bd_addr_evt[11] = ((randNum>>8) & 0xFF);
  1266. +                    bt_get_bd_addr_evt[7] = (randNum & 0xFF);
  1267. +                    
  1268. +                    cfg.addr[0] = bt_get_bd_addr_evt[12];
  1269. +                    cfg.addr[1] = bt_get_bd_addr_evt[11];
  1270. +                    cfg.addr[5] = bt_get_bd_addr_evt[7];
  1271. +                #endif
  1272. +                }
  1273. +                else {
  1274. +                    /* eFUSE address has valid value */
  1275. +                }
  1276. +
  1277. +                memcpy(&bt_set_bd_addr[4], &bt_get_bd_addr_evt[7], 6);
  1278. +
  1279. +                /* Update BD address in internal BT config file */
  1280. +                pos = 0;
  1281. +                written = file_write(INTERNAL_BT_CFG_FILE,
  1282. +                                     (char*)&cfg,
  1283. +                                     6,
  1284. +                                     &pos);
  1285. +
  1286. +                /* Clear flag */
  1287. +                fgetEFUSE = false;
  1288. +            }
  1289. +            /* Process next cmd */
  1290. +            continue;
  1291. +        }
  1292. +        else {
  1293. +            BT_ERR_FUNC("EVT(%d) ret(%u) rx_flag(%d)<=\n",
  1294. +                idx, jiffies_to_msecs(ret), phu->init_evt_rx_flag);
  1295. +            /* Stop processing and skip next cmd */
  1296. +            break;
  1297. +        }
  1298. +    }
  1299. +
  1300. +    if (phu->p_init_comp) {
  1301. +        complete(phu->p_init_comp);
  1302. +    }
  1303. +}
  1304. +
  1305. +static int hci_stp_dev_init (struct hci_stp *phu)
  1306. +{
  1307. +    DECLARE_COMPLETION_ONSTACK(hci_stp_dev_init_comp);
  1308. +    DECLARE_WAIT_QUEUE_HEAD_ONSTACK(hci_stp_dev_init_wq);
  1309. +
  1310. +    spin_lock(&phu->init_lock);
  1311. +    phu->p_init_comp = &hci_stp_dev_init_comp;
  1312. +    phu->p_init_evt_wq = &hci_stp_dev_init_wq;
  1313. +    spin_unlock(&phu->init_lock);
  1314. +
  1315. +    /* unregister rx event callback */
  1316. +    mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);
  1317. +    /* register direct rx callback for init only */
  1318. +//WATWATWATWATWATWAT
  1319. +    mtk_wcn_stp_register_if_rx(hci_stp_dev_init_rx_cb);
  1320. +    /* use bluez mode */
  1321. +    mtk_wcn_stp_set_bluez(1);
  1322. +
  1323. +    /* Schedule to call hci_stp_dev_init_work(). init_work is initialized in
  1324. +     * hci_stp_init().
  1325. +     */
  1326. +    schedule_work(&phu->init_work);
  1327. +
  1328. +    wait_for_completion(&hci_stp_dev_init_comp);
  1329. +
  1330. +    spin_lock(&phu->init_lock);
  1331. +    /* clear references to stack variables */
  1332. +    phu->p_init_comp = NULL;
  1333. +    phu->p_init_evt_wq = NULL;
  1334. +    spin_unlock(&phu->init_lock);
  1335. +
  1336. +    /* check result */
  1337. +    /* flag: (to be replaced by a constant value)
  1338. +        1 rx event correctly,
  1339. +        0 no response in time,
  1340. +        -1 unequal rx event length,
  1341. +        -2 unequal rx event content.
  1342. +    */
  1343. +    if (likely(1 == phu->init_evt_rx_flag)) {
  1344. +        return 0;
  1345. +    }
  1346. +    else {
  1347. +        /* return non-zero value for error */
  1348. +        return (phu->init_evt_rx_flag + 256);
  1349. +    }
  1350. +}
  1351. +
  1352. +/* Invoked when there is ONE received BT packet */
  1353. +void stp_tx_event_cb(void)
  1354. +{
  1355. +#if 0
  1356. +    struct hci_stp *hu;
  1357. +    if (unlikely(hdev == NULL)) {
  1358. +        BT_ERR_FUNC("Null hdev!\n");
  1359. +        BUG_ON(hdev == NULL);
  1360. +        return;
  1361. +    }
  1362. +    hu = (struct hci_stp *) hdev->driver_data;
  1363. +#endif
  1364. +    /* George: [FixMe] can we call hci_stp_tx_wakeup() directly in STP-CORE's
  1365. +     * context? It seems to be dangerous! Replace it with suitable one according
  1366. +     * to HCI_STP_TX compile flag.
  1367. +     */
  1368. +    hci_stp_tx_kick(); /* George: adapt different tx_kick function */
  1369. +}
  1370. +
  1371. +/*
  1372. +  Direct delivery of bluez not changed hands through the stp buffer
  1373. +*/
  1374. +void stp_rx_event_cb_directly(const UINT8 *data, INT32 count)
  1375. +{
  1376. +    register const UINT8 *ptr;
  1377. +    struct hci_event_hdr *eh;
  1378. +    struct hci_acl_hdr   *ah;
  1379. +    struct hci_sco_hdr   *sh;
  1380. +    register int len, type, dlen;
  1381. +    int while_count; /* = 0; Is while_count redundant? */
  1382. +    //static unsigned long rx_count; /* Is it ok w/o an initial value??? */
  1383. +    static unsigned int rx_count = 0;
  1384. +    //static unsigned long rx_state; /* Is it ok w/o an initial value??? */
  1385. +    static unsigned int rx_state = H4_W4_PACKET_TYPE;
  1386. +    struct  sk_buff *rx_skb = NULL; /* Is it ok to use non-static skb??? */
  1387. +    register int room;
  1388. +#if HCI_STP_SAFE_RESET
  1389. +    struct hci_stp *hu;
  1390. +#endif
  1391. +
  1392. +    BT_LOUD_FUNC("count(%d)rx_state(%d)rx_count(%d)\n",
  1393. +        count, rx_state, rx_count);
  1394. +
  1395. +    if (data == NULL) {
  1396. +        BT_ERR_FUNC("Data is Null\n");
  1397. +        return;
  1398. +    }
  1399. +
  1400. +    if (count > 5000) {
  1401. +        BT_WARN_FUNC("abnormal count(%d)\n", count);
  1402. +    }
  1403. +
  1404. +    ptr = data;
  1405. +    /*Add statistic*/
  1406. +    hdev->stat.byte_rx += count;
  1407. +
  1408. +#if HCI_STP_SAFE_RESET
  1409. +    hu = (struct hci_stp *)hdev->driver_data;
  1410. +    /* is waiting hci reset event? */
  1411. +    if (unlikely(atomic_read(&hu->reset_count))) {
  1412. +        if (count == ARRAY_SIZE(bt_reset_evt)) {
  1413. +            if (!memcmp(bt_reset_evt, data, ARRAY_SIZE(bt_reset_evt))) {
  1414. +                BT_DBG_FUNC("hci reset evt,f(%d),c(%d)\n",
  1415. +                    BT_GET_HDEV_RST_FG(hdev),
  1416. +                    atomic_read(&hu->reset_count));
  1417. +
  1418. +                atomic_dec(&hu->reset_count);
  1419. +                wake_up(&hu->reset_wq);
  1420. +            }
  1421. +        }
  1422. +    }
  1423. +#endif
  1424. +
  1425. +    while_count = 0;
  1426. +    while (count > 0) { /* while (count) */
  1427. +        /* Is while_count redundant? */
  1428. +        //while_count++;
  1429. +        if (++while_count > 5000) {
  1430. +            BT_WARN_FUNC("abnormal while_count(%d)\n", while_count);
  1431. +        }
  1432. +
  1433. +        if (rx_count) {
  1434. +            len = min_t(unsigned int, rx_count, count);
  1435. +            memcpy(skb_put(rx_skb, len), ptr, len);
  1436. +            rx_count -= len;
  1437. +            count -= len;
  1438. +            ptr += len;
  1439. +
  1440. +            if (rx_count)
  1441. +                continue;
  1442. +            /* rx_count==0, ready to indicate to hci_core */
  1443. +
  1444. +            switch (rx_state) {
  1445. +            case H4_W4_DATA:
  1446. +                BT_LOUD_FUNC("Complete data\n");
  1447. +                hci_recv_frame(hdev,rx_skb);
  1448. +                rx_state = H4_W4_PACKET_TYPE;
  1449. +                rx_skb = NULL;
  1450. +                continue;
  1451. +
  1452. +            case H4_W4_EVENT_HDR:
  1453. +                eh = hci_event_hdr(rx_skb);
  1454. +                //BT_DBG_FUNC("Event header:evt(0x%2.2x)plen(%d)\n", eh->evt, eh->plen);
  1455. +                room = skb_tailroom(rx_skb);
  1456. +                //BT_DBG_FUNC("len(%d)room(%d)\n", eh->plen, room);
  1457. +                BT_LOUD_FUNC("Event header:evt(0x%2.2x)plen(%d)room(%d)\n",
  1458. +                    eh->evt, eh->plen, room);
  1459. +
  1460. +                if (!eh->plen) {
  1461. +                    hci_recv_frame(hdev, rx_skb);
  1462. +                    rx_state = H4_W4_PACKET_TYPE;
  1463. +                    rx_skb   = NULL;
  1464. +                    rx_count = 0; /* redundant? here rx_count is 0 already */
  1465. +                }
  1466. +                else if (eh->plen > room) {
  1467. +                    //BT_ERR("Data length is too large\n");
  1468. +                    BT_ERR_FUNC("too large data length:eh->plen(%d)>room(%d)\n",
  1469. +                        eh->plen, room);
  1470. +                    kfree_skb(rx_skb);
  1471. +                    rx_state = H4_W4_PACKET_TYPE;
  1472. +                    rx_skb = NULL;
  1473. +                    rx_count = 0; /* redundant? here rx_count is 0 already */
  1474. +                }
  1475. +                else {
  1476. +                    rx_state = H4_W4_DATA;
  1477. +                    rx_count = eh->plen;
  1478. +                }
  1479. +                continue;
  1480. +
  1481. +            case H4_W4_ACL_HDR:
  1482. +                ah = hci_acl_hdr(rx_skb);
  1483. +                dlen = __le16_to_cpu(ah->dlen);
  1484. +
  1485. +                room = skb_tailroom(rx_skb);
  1486. +                BT_LOUD_FUNC("ACL header:dlen(%d)room(%d)\n", dlen, room);
  1487. +                if (!dlen) {
  1488. +                    hci_recv_frame(hdev, rx_skb);
  1489. +                    rx_state = H4_W4_PACKET_TYPE;
  1490. +                    rx_skb = NULL;
  1491. +                    rx_count = 0;
  1492. +                }
  1493. +                else if (dlen > room) {
  1494. +                    //BT_ERR_FUNC("Data length is too large\n");
  1495. +                    BT_ERR_FUNC("too large data length:dlen(%d)>room(%d)\n",
  1496. +                        dlen, room);
  1497. +                    kfree_skb(rx_skb);
  1498. +                    rx_state = H4_W4_PACKET_TYPE;
  1499. +                    rx_skb = NULL;
  1500. +                    rx_count = 0;
  1501. +                }
  1502. +                else {
  1503. +                    rx_state = H4_W4_DATA;
  1504. +                    rx_count = dlen;
  1505. +                }
  1506. +                continue;
  1507. +
  1508. +            case H4_W4_SCO_HDR:
  1509. +                sh = hci_sco_hdr(rx_skb);
  1510. +                room = skb_tailroom(rx_skb);
  1511. +                BT_LOUD_FUNC("SCO header:dlen(%d)room(%d)\n", sh->dlen, room);
  1512. +
  1513. +                if (!sh->dlen) {
  1514. +                    hci_recv_frame(hdev, rx_skb);
  1515. +                    rx_state = H4_W4_PACKET_TYPE;
  1516. +                    rx_skb = NULL;
  1517. +                    rx_count = 0;
  1518. +                }
  1519. +                else if (sh->dlen > room) {
  1520. +                    BT_ERR_FUNC("Data length is too large\n");
  1521. +                    BT_ERR_FUNC("too large data length:sh->dlen(%d)>room(%d)\n",
  1522. +                        sh->dlen , room);
  1523. +                    kfree_skb(rx_skb);
  1524. +                    rx_state = H4_W4_PACKET_TYPE;
  1525. +                    rx_skb = NULL;
  1526. +                    rx_count = 0;
  1527. +                }
  1528. +                else {
  1529. +                    rx_state = H4_W4_DATA;
  1530. +                    rx_count = sh->dlen;
  1531. +                }
  1532. +                continue;
  1533. +            }
  1534. +        }
  1535. +
  1536. +        /* H4_W4_PACKET_TYPE */
  1537. +        switch (*ptr) {
  1538. +            case HCI_EVENT_PKT:
  1539. +                BT_LOUD_FUNC("Event packet\n");
  1540. +                rx_state = H4_W4_EVENT_HDR;
  1541. +                rx_count = HCI_EVENT_HDR_SIZE;
  1542. +                type = HCI_EVENT_PKT;
  1543. +                break;
  1544. +
  1545. +            case HCI_ACLDATA_PKT:
  1546. +                BT_LOUD_FUNC("ACL packet\n");
  1547. +                rx_state = H4_W4_ACL_HDR;
  1548. +                rx_count = HCI_ACL_HDR_SIZE;
  1549. +                type = HCI_ACLDATA_PKT;
  1550. +                break;
  1551. +
  1552. +            case HCI_SCODATA_PKT:
  1553. +                BT_LOUD_FUNC("SCO packet\n");
  1554. +                rx_state = H4_W4_SCO_HDR;
  1555. +                rx_count = HCI_SCO_HDR_SIZE;
  1556. +                type = HCI_SCODATA_PKT;
  1557. +                break;
  1558. +
  1559. +            default:
  1560. +                BT_ERR_FUNC("Unknown HCI packet type %2.2x\n", (__u8)*ptr);
  1561. +                ++(hdev->stat.err_rx);
  1562. +                ++ptr;
  1563. +                --count;
  1564. +                continue;
  1565. +        };
  1566. +
  1567. +        ++ptr;
  1568. +        --count;
  1569. +
  1570. +        /* Allocate packet */
  1571. +        rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
  1572. +        if (!rx_skb) {
  1573. +           BT_ERR_FUNC("bt_skb_alloc(%d, GFP_ATOMIC) fail!\n", HCI_MAX_FRAME_SIZE);
  1574. +           rx_state = H4_W4_PACKET_TYPE;
  1575. +           rx_count = 0;
  1576. +           return;
  1577. +        }
  1578. +
  1579. +        rx_skb->dev = (void *) hdev;
  1580. +        bt_cb(rx_skb)->pkt_type = type;
  1581. +    }
  1582. +
  1583. +    return;
  1584. +}
  1585. +
  1586. +/* ------- Interface to HCI layer ------ */
  1587. +/* Initialize device */
  1588. +static int hci_stp_open(struct hci_dev *hdev)
  1589. +{
  1590. +    struct hci_stp *hu;
  1591. +    int ret;
  1592. +
  1593. +    if (unlikely(!hdev)) {
  1594. +        BT_ERR_FUNC("null hdev\n");
  1595. +        return -ENODEV;
  1596. +    }
  1597. +
  1598. +    if (unlikely(!hdev->driver_data)) {
  1599. +        BT_ERR_FUNC("null hdev\n");
  1600. +        return -ENODEV;
  1601. +    }
  1602. +
  1603. +    hu = (struct hci_stp *)hdev->driver_data;
  1604. +    BT_INFO_FUNC("%s(0x%p)\n", hdev->name, hdev);
  1605. +
  1606. +    /* clear txq and free all skb in it */
  1607. +    hci_stp_txq_lock(HCI_STP_TXQ_IN_BLZ);
  1608. +    skb_queue_purge(&hu->txq);
  1609. +    hci_stp_txq_unlock(HCI_STP_TXQ_IN_BLZ);
  1610. +
  1611. +    /* turn on BT */
  1612. +    if (unlikely(MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT))) {
  1613. +        BT_WARN_FUNC("WMT turn on BT fail!\n");
  1614. +        return -ENODEV;
  1615. +    }
  1616. +
  1617. +    BT_INFO_FUNC("WMT turn on BT OK!\n");
  1618. +
  1619. +    if (likely(mtk_wcn_stp_is_ready())) {
  1620. +        BT_DBG_FUNC("STP is ready!\n");
  1621. +
  1622. +        ret = hci_stp_dev_init(hu);
  1623. +        /* error handling: turn off BT */
  1624. +        if (unlikely(ret)) {
  1625. +            BT_WARN_FUNC("hci_stp_dev_init fail(%d)!\n", ret);
  1626. +            if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) {
  1627. +                BT_WARN_FUNC("WMT turn off BT fail!\n");
  1628. +            }
  1629. +            else {
  1630. +                BT_INFO_FUNC("WMT turn off BT ok!\n");
  1631. +            }
  1632. +            return -ENODEV;
  1633. +        }
  1634. +
  1635. +        BT_INFO_FUNC("hci_stp_dev_init ok\n");
  1636. +
  1637. +        set_bit(HCI_RUNNING, &hdev->flags);
  1638. +
  1639. +        /* registered tx/rx path */
  1640. +//WATWATWATWATWATWAT
  1641. +        mtk_wcn_stp_register_if_rx(stp_rx_event_cb_directly);
  1642. +
  1643. +        mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);
  1644. +        mtk_wcn_stp_register_tx_event_cb(BT_TASK_INDX, stp_tx_event_cb);
  1645. +
  1646. +        /* use bluez */
  1647. +        mtk_wcn_stp_set_bluez(1);
  1648. +
  1649. +        return 0;
  1650. +    }
  1651. +    else {
  1652. +        BT_WARN_FUNC("STP is not ready!\n");
  1653. +        return -ENODEV;
  1654. +    }
  1655. +}
  1656. +
  1657. +/* Reset device */
  1658. +static int hci_stp_flush(struct hci_dev *hdev)
  1659. +{
  1660. +    struct hci_stp *hu;
  1661. +
  1662. +    BT_DBG_FUNC("start\n");
  1663. +    if (!hdev || !hdev->driver_data) {
  1664. +        BT_WARN_FUNC("invalid hdev(0x%p) or drv data(0x%p)\n",
  1665. +            hdev, (hdev) ? hdev->driver_data : hdev);
  1666. +        return -EFAULT;
  1667. +    }
  1668. +
  1669. +    hu = (struct hci_stp *)hdev->driver_data;
  1670. +
  1671. +    /* clear txq and free all skb in it */
  1672. +    hci_stp_txq_lock(HCI_STP_TXQ_IN_BLZ);
  1673. +    skb_queue_purge(&hu->txq);
  1674. +    hci_stp_txq_unlock(HCI_STP_TXQ_IN_BLZ);
  1675. +
  1676. +    BT_INFO_FUNC("done\n");
  1677. +    return 0;
  1678. +}
  1679. +
  1680. +/* Close device */
  1681. +static int hci_stp_close(struct hci_dev *hdev)
  1682. +{
  1683. +#if HCI_STP_SAFE_RESET
  1684. +    struct hci_stp *hu;
  1685. +    long ret;
  1686. +#endif
  1687. +
  1688. +    BT_INFO_FUNC("hdev(0x%p)\n", hdev);
  1689. +
  1690. +    if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) {
  1691. +          return 0;
  1692. +    }
  1693. +
  1694. +    hci_stp_flush(hdev);
  1695. +    hdev->flush = NULL;
  1696. +
  1697. +#if HCI_STP_SAFE_RESET
  1698. +    hu = (struct hci_stp *)hdev->driver_data;
  1699. +    if (hu) {
  1700. +        /* double waiting time in case of busy system */
  1701. +        ret = wait_event_timeout((hu->reset_wq),
  1702. +            (atomic_read(&hu->reset_count) == 0),
  1703. +            msecs_to_jiffies(BT_CMD_DELAY_MS_RESET*2));
  1704. +        if ( (!ret) || (atomic_read(&hu->reset_count) != 0) ) {
  1705. +            BT_WARN_FUNC("wait on-going reset finish fail,f(%d),c(%d),ret(%u)\n",
  1706. +                BT_GET_HDEV_RST_FG(hdev),
  1707. +                atomic_read(&hu->reset_count),
  1708. +                jiffies_to_msecs(ret));
  1709. +        }
  1710. +        else {
  1711. +            BT_DBG_FUNC("check reset log,f(%d),c(%d),ret(%u)\n",
  1712. +                BT_GET_HDEV_RST_FG(hdev),
  1713. +                atomic_read(&hu->reset_count),
  1714. +                jiffies_to_msecs(ret));
  1715. +        }
  1716. +    }
  1717. +#endif
  1718. +
  1719. +    /* clear txq and free all skb in it */
  1720. +    hci_stp_txq_lock(HCI_STP_TXQ_IN_BLZ);
  1721. +    skb_queue_purge(&hu->txq);
  1722. +    hci_stp_txq_unlock(HCI_STP_TXQ_IN_BLZ);
  1723. +
  1724. +    /* unregistered tx/rx path */
  1725. +    mtk_wcn_stp_register_if_rx(NULL);
  1726. +
  1727. +    mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);
  1728. +    mtk_wcn_stp_register_tx_event_cb(BT_TASK_INDX, NULL);
  1729. +
  1730. +    /* not use bluez */
  1731. +    mtk_wcn_stp_set_bluez(0);
  1732. +
  1733. +    if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) {
  1734. +        BT_WARN_FUNC("WMT turn off BT fail!\n");
  1735. +    }
  1736. +    else {
  1737. +        BT_INFO_FUNC("WMT turn off BT OK!\n");
  1738. +    }
  1739. +
  1740. +    return 0;
  1741. +}
  1742. +
  1743. +/* Send frames from HCI layer */
  1744. +static int hci_stp_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
  1745. +{
  1746. +    struct hci_stp *hu;
  1747. +
  1748. +    if (!hdev) {
  1749. +        BT_ERR_FUNC("Null hdev in skb\n");
  1750. +        return -ENODEV;
  1751. +    }
  1752. +
  1753. +    if (!test_bit(HCI_RUNNING, &hdev->flags)) {
  1754. +        BT_ERR_FUNC("no HCI_RUNNING in hdev->flags(0x%lx)\n", hdev->flags);
  1755. +        return -EBUSY;
  1756. +    }
  1757. +
  1758. +    hu = (struct hci_stp *) hdev->driver_data;
  1759. +
  1760. +    BT_LOUD_FUNC("%s: type(%d) len(%d)\n",
  1761. +        hdev->name, bt_cb(skb)->pkt_type, skb->len);
  1762. +
  1763. +#if 0 /* just timestamp?? */
  1764. +    if (gDbgLevel >= BT_LOG_DBG)
  1765. +    {
  1766. +        struct timeval now;
  1767. +        do_gettimeofday(&now);
  1768. +        printk("%s: sec = %ld, --> usec --> %ld\n",
  1769. +             __FUNCTION__, now.tv_sec, now.tv_usec);
  1770. +    }
  1771. +#endif
  1772. +
  1773. +    /* Prepend skb with frame type. Is it safe to do skb_push? */
  1774. +    memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
  1775. +
  1776. +    /* George: is no lock ok?? Add hci_stp_txq_lock and unlock! */
  1777. +    hci_stp_txq_lock(HCI_STP_TXQ_IN_BLZ);
  1778. +    /*Queue a buffer at the end of a list. This function takes no locks
  1779. +    *  and you must therefore hold required locks before calling it.
  1780. +    */
  1781. +    skb_queue_tail(&hu->txq, skb);
  1782. +    hci_stp_txq_unlock(HCI_STP_TXQ_IN_BLZ);
  1783. +
  1784. +    /* George: adapt different tx_kick function */
  1785. +    hci_stp_tx_kick();
  1786. +
  1787. +    return 0;
  1788. +}
  1789. +
  1790. +static int __init hci_stp_init(void)
  1791. +{
  1792. +    struct hci_stp *hu = NULL;
  1793. +
  1794. +    if (!(hu = kzalloc(sizeof(struct hci_stp), GFP_ATOMIC))) {
  1795. +        BT_ERR_FUNC("Can't allocate control structure\n");
  1796. +        return -ENOMEM;
  1797. +    }
  1798. +
  1799. +    /*
  1800. +       used to stored pending skb
  1801. +     */
  1802. +    skb_queue_head_init(&hu->txq);
  1803. +
  1804. +    /*
  1805. +       Initialize and register HCI device
  1806. +     */
  1807. +    hdev = hci_alloc_dev();
  1808. +    if (!hdev) {
  1809. +        if (hu){
  1810. +            kfree(hu);
  1811. +            hu = NULL;
  1812. +        }
  1813. +
  1814. +        BT_ERR_FUNC("Can't allocate HCI device\n");
  1815. +        return -ENOMEM;
  1816. +    }
  1817. +
  1818. +    hu->hdev = hdev;
  1819. +
  1820. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
  1821. +    hdev->type = HCI_UART;
  1822. +#else
  1823. +    hdev->bus = HCI_UART;
  1824. +    hdev->dev_type = HCI_BREDR;
  1825. +#endif
  1826. +    hdev->driver_data = hu;
  1827. +
  1828. +    BT_DBG_FUNC("hdev->driver_data\n");
  1829. +    hdev->open  = hci_stp_open;
  1830. +    hdev->close = hci_stp_close;
  1831. +    hdev->flush = hci_stp_flush;
  1832. +    hdev->send  = hci_stp_send_frame;
  1833. +
  1834. +    BT_DBG_FUNC("HCI_QUIRK_NO_RESET\n");
  1835. +
  1836. +    set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
  1837. +
  1838. +    if (hci_register_dev(hdev) < 0) {
  1839. +        BT_ERR_FUNC("Can't register HCI device\n");
  1840. +        kfree(hu);
  1841. +        hu = NULL;
  1842. +        hci_free_dev(hdev);
  1843. +        hdev = NULL;
  1844. +        return -ENODEV;
  1845. +     }
  1846. +
  1847. +#if HCI_STP_SAFE_RESET
  1848. +    atomic_set(&hu->reset_count, 0);
  1849. +    init_waitqueue_head(&hu->reset_wq);
  1850. +#endif
  1851. +
  1852. +    /* George: adapt different tx_init function */
  1853. +    hci_stp_tx_init(hu);
  1854. +
  1855. +    /* init_work in heap */
  1856. +    INIT_WORK(&hu->init_work, hci_stp_dev_init_work);
  1857. +    spin_lock_init(&hu->init_lock);
  1858. +
  1859. +    mtk_wcn_stp_register_if_rx(NULL);
  1860. +    mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);
  1861. +    mtk_wcn_stp_register_tx_event_cb(BT_TASK_INDX, NULL);
  1862. +
  1863. +    BT_INFO_FUNC("HCI STP driver ver %s, hdev(0x%p), init done\n", VERSION, hdev);
  1864. +
  1865. +    return 0;
  1866. +}
  1867. +
  1868. +static void __exit hci_stp_exit(void)
  1869. +{
  1870. +    struct hci_stp *hu = (struct hci_stp *)hdev->driver_data;
  1871. +
  1872. +    BT_TRC_FUNC();
  1873. +
  1874. +    mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);
  1875. +    mtk_wcn_stp_register_tx_event_cb(BT_TASK_INDX, NULL);
  1876. +
  1877. +    hci_unregister_dev(hdev);
  1878. +
  1879. +    /* George: adapt different tx_deinit function */
  1880. +    //tasklet_kill(&hci_tx_tasklet);
  1881. +
  1882. +    skb_queue_purge(&hu->txq);
  1883. +
  1884. +    kfree(hdev->driver_data);
  1885. +    hci_free_dev(hdev);
  1886. +
  1887. +    hdev = NULL;
  1888. +}
  1889. +
  1890. +module_init(hci_stp_init);
  1891. +module_exit(hci_stp_exit);
  1892. +
  1893. +module_param(reset, bool, 0644);
  1894. +MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
  1895. +
  1896. +MODULE_AUTHOR("Mediatek Inc.");
  1897. +MODULE_DESCRIPTION("Bluetooth HCI STP driver ver " VERSION);
  1898. +MODULE_LICENSE("GPL");
  1899. diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
  1900. index 37ff1ae..ba72581 100644
  1901. --- a/include/net/bluetooth/hci_core.h
  1902. +++ b/include/net/bluetooth/hci_core.h
  1903. @@ -303,6 +303,7 @@ struct hci_dev {
  1904.     __u32           req_result;
  1905.  
  1906.     void            *smp_data;
  1907. +   void            *driver_data;
  1908.  
  1909.     struct discovery_state  discovery;
  1910.     struct hci_conn_hash    conn_hash;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement