gl_bow.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  1. /*
  2. ** Id: @(#) gl_bow.c@@
  3. */
  4. /*! \file gl_bow.c
  5. \brief Main routines of Linux driver interface for 802.11 PAL (BT 3.0 + HS)
  6. This file contains the main routines of Linux driver for MediaTek Inc. 802.11
  7. Wireless LAN Adapters.
  8. */
  9. /*
  10. ** Log: gl_bow.c
  11. *
  12. * 02 16 2012 chinghwa.yu
  13. * [WCXRP00000065] Update BoW design and settings
  14. * [ALPS00235223] [Rose][ICS][Cross Feature][AEE-IPANIC]The device reboot automatically and then the "KE" pops up
  15. * after you turn on the "Airplane mode".(once)
  16. *
  17. * [Root Cause]
  18. * PAL operates BOW char dev poll after BOW char dev is registered.
  19. *
  20. * [Solution]
  21. * Rejects PAL char device operation after BOW is unregistered or when wlan GLUE_FLAG_HALT is set.
  22. *
  23. * This is a workaround for BOW driver robustness, happens only in ICS.
  24. *
  25. * Root cause should be fixed by CR [ALPS00231570]
  26. *
  27. * 02 03 2012 chinghwa.yu
  28. * [WCXRP00000065] Update BoW design and settings
  29. * [ALPS00118114] [Rose][ICS][Free Test][Bluetooth]The "KE" pops up after you turn on the airplane mode.(5/5)
  30. *
  31. * [Root Cause]
  32. * PAL operates BOW char dev poll after BOW char dev is registered.
  33. *
  34. * [Solution]
  35. * Rejects PAL char device operation after BOW is unregistered.
  36. *
  37. * Happens only in ICS.
  38. *
  39. * Notified PAL owener to reivew MTKBT/PAL closing BOW char dev procedure.
  40. *
  41. * [Side Effect]
  42. * None.
  43. *
  44. * 01 16 2012 chinghwa.yu
  45. * [WCXRP00000065] Update BoW design and settings
  46. * Support BOW for 5GHz band.
  47. *
  48. * 11 10 2011 cp.wu
  49. * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
  50. * 1. eliminaite direct calls to printk in porting layer.
  51. * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
  52. *
  53. * 10 25 2011 chinghwa.yu
  54. * [WCXRP00000065] Update BoW design and settings
  55. * Modify ampc0 char device for major number 151 for all MT6575 projects.
  56. *
  57. * 07 28 2011 cp.wu
  58. * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl
  59. * unlocked_ioctl returns as long instead of int.
  60. *
  61. * 07 28 2011 cp.wu
  62. * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl
  63. * migrate to unlocked ioctl interface
  64. *
  65. * 04 12 2011 chinghwa.yu
  66. * [WCXRP00000065] Update BoW design and settings
  67. * Add WMM IE for BOW initiator data.
  68. *
  69. * 04 10 2011 chinghwa.yu
  70. * [WCXRP00000065] Update BoW design and settings
  71. * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes.
  72. *
  73. * 04 09 2011 chinghwa.yu
  74. * [WCXRP00000065] Update BoW design and settings
  75. * Change Link connection event procedure and change skb length check to 1512 bytes.
  76. *
  77. * 03 27 2011 chinghwa.yu
  78. * [WCXRP00000065] Update BoW design and settings
  79. * Support multiple physical link.
  80. *
  81. * 03 06 2011 chinghwa.yu
  82. * [WCXRP00000065] Update BoW design and settings
  83. * Sync BOW Driver to latest person development branch version..
  84. *
  85. * 03 03 2011 jeffrey.chang
  86. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  87. * support concurrent network
  88. *
  89. * 03 03 2011 jeffrey.chang
  90. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  91. * replace alloc_netdev to alloc_netdev_mq for BoW
  92. *
  93. * 03 03 2011 jeffrey.chang
  94. * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
  95. * modify net device relative functions to support multiple H/W queues
  96. *
  97. * 02 15 2011 chinghwa.yu
  98. * [WCXRP00000065] Update BoW design and settings
  99. * Update net register and BOW for concurrent features.
  100. *
  101. * 02 10 2011 chinghwa.yu
  102. * [WCXRP00000065] Update BoW design and settings
  103. * Fix kernel API change issue.
  104. * Before ALPS 2.2 (2.2 included), kfifo_alloc() is
  105. * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock);
  106. * After ALPS 2.3, kfifo_alloc() is changed to
  107. * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask);
  108. *
  109. * 02 09 2011 cp.wu
  110. * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3
  111. * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031
  112. * with BOW and P2P enabled as default
  113. *
  114. * 02 08 2011 chinghwa.yu
  115. * [WCXRP00000065] Update BoW design and settings
  116. * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in.
  117. * Update BOW get MAC status, remove returning event for AIS network type.
  118. *
  119. * 01 12 2011 cp.wu
  120. * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
  121. * implementation of separate BT_OVER_WIFI data path.
  122. *
  123. * 01 12 2011 cp.wu
  124. * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation
  125. * needs such information
  126. * fill mac header length information for 802.1x frames.
  127. *
  128. * 11 11 2010 chinghwa.yu
  129. * [WCXRP00000065] Update BoW design and settings
  130. * Fix BoW timer assert issue.
  131. *
  132. * 09 14 2010 chinghwa.yu
  133. * NULL
  134. * Add bowRunEventAAAComplete.
  135. *
  136. * 09 14 2010 cp.wu
  137. * NULL
  138. * correct typo: POLLOUT instead of POLL_OUT
  139. *
  140. * 09 13 2010 cp.wu
  141. * NULL
  142. * add waitq for poll() and read().
  143. *
  144. * 08 24 2010 chinghwa.yu
  145. * NULL
  146. * Update BOW for the 1st time.
  147. *
  148. * 07 08 2010 cp.wu
  149. *
  150. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  151. *
  152. * 06 06 2010 kevin.huang
  153. * [WPD00003832][MT6620 5931] Create driver base
  154. * [MT6620 5931] Create driver base
  155. *
  156. * 05 05 2010 cp.wu
  157. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  158. * change variable names for multiple physical link to match with coding convention
  159. *
  160. * 05 05 2010 cp.wu
  161. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  162. * multiple BoW interfaces need to compare with peer address
  163. *
  164. * 04 28 2010 cp.wu
  165. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  166. * change prefix for data structure used to communicate with 802.11 PAL
  167. * to avoid ambiguous naming with firmware interface
  168. *
  169. * 04 28 2010 cp.wu
  170. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  171. * fix kalIndicateBOWEvent.
  172. *
  173. * 04 27 2010 cp.wu
  174. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  175. * add multiple physical link support
  176. *
  177. * 04 13 2010 cp.wu
  178. * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
  179. * add framework for BT-over-Wi-Fi support.
  180. * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
  181. * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically
  182. * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose
  183. **
  184. */
  185. /*******************************************************************************
  186. * C O M P I L E R F L A G S
  187. ********************************************************************************
  188. */
  189. /*******************************************************************************
  190. * E X T E R N A L R E F E R E N C E S
  191. ********************************************************************************
  192. */
  193. #include "gl_os.h"
  194. #include "debug.h"
  195. #include "wlan_lib.h"
  196. #include "gl_wext.h"
  197. #include "precomp.h"
  198. #include <linux/poll.h>
  199. #include "bss.h"
  200. #if CFG_ENABLE_BT_OVER_WIFI
  201. /*******************************************************************************
  202. * C O N S T A N T S
  203. ********************************************************************************
  204. */
  205. /* @FIXME if there is command/event with payload length > 28 */
  206. #define MAX_BUFFER_SIZE (64)
  207. /*******************************************************************************
  208. * D A T A T Y P E S
  209. ********************************************************************************
  210. */
  211. /*******************************************************************************
  212. * P U B L I C D A T A
  213. ********************************************************************************
  214. */
  215. #if CFG_BOW_TEST
  216. UINT_32 g_u4PrevSysTime = 0;
  217. UINT_32 g_u4CurrentSysTime = 0;
  218. UINT_32 g_arBowRevPalPacketTime[11];
  219. #endif
  220. /*******************************************************************************
  221. * P R I V A T E D A T A
  222. ********************************************************************************
  223. */
  224. /* forward declarations */
  225. static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos);
  226. static ssize_t
  227. mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos);
  228. static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg);
  229. static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait);
  230. static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp);
  231. static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp);
  232. /* character file operations */
  233. static const struct file_operations mt6620_ampc_fops = {
  234. /* .owner = THIS_MODULE, */
  235. .read = mt6620_ampc_read,
  236. .write = mt6620_ampc_write,
  237. .unlocked_ioctl = mt6620_ampc_ioctl,
  238. .poll = mt6620_ampc_poll,
  239. .open = mt6620_ampc_open,
  240. .release = mt6620_ampc_release,
  241. };
  242. /*******************************************************************************
  243. * M A C R O S
  244. ********************************************************************************
  245. */
  246. /*******************************************************************************
  247. * F U N C T I O N D E C L A R A T I O N S
  248. ********************************************************************************
  249. */
  250. /*******************************************************************************
  251. * F U N C T I O N S
  252. ********************************************************************************
  253. */
  254. /*----------------------------------------------------------------------------*/
  255. /*!
  256. * \brief Register for character device to communicate with 802.11 PAL
  257. *
  258. * \param[in] prGlueInfo Pointer to glue info
  259. *
  260. * \return TRUE
  261. * FALSE
  262. */
  263. /*----------------------------------------------------------------------------*/
  264. BOOLEAN glRegisterAmpc(IN P_GLUE_INFO_T prGlueInfo)
  265. {
  266. ASSERT(prGlueInfo);
  267. if (prGlueInfo->rBowInfo.fgIsRegistered == TRUE)
  268. return FALSE;
  269. #if 0
  270. /* 1. allocate major number dynamically */
  271. if (alloc_chrdev_region(&(prGlueInfo->rBowInfo.u4DeviceNumber), 0, /* first minor number */
  272. 1, /* number */
  273. GLUE_BOW_DEVICE_NAME) != 0)
  274. return FALSE;
  275. #endif
  276. #if 1
  277. #if defined(CONFIG_AMPC_CDEV_NUM)
  278. prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(CONFIG_AMPC_CDEV_NUM, 0);
  279. #else
  280. prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(226, 0);
  281. #endif
  282. if (register_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1, /* number */
  283. GLUE_BOW_DEVICE_NAME) != 0)
  284. return FALSE;
  285. #endif
  286. /* 2. spin-lock initialization */
  287. /* spin_lock_init(&(prGlueInfo->rBowInfo.rSpinLock)); */
  288. /* 3. initialize kfifo */
  289. /* prGlueInfo->rBowInfo.prKfifo = kfifo_alloc(GLUE_BOW_KFIFO_DEPTH,
  290. GFP_KERNEL,
  291. &(prGlueInfo->rBowInfo.rSpinLock));*/
  292. if ((kfifo_alloc((struct kfifo *)&(prGlueInfo->rBowInfo.rKfifo), GLUE_BOW_KFIFO_DEPTH, GFP_KERNEL)))
  293. goto fail_kfifo_alloc;
  294. /* if(prGlueInfo->rBowInfo.prKfifo == NULL) */
  295. if (&(prGlueInfo->rBowInfo.rKfifo) == NULL)
  296. goto fail_kfifo_alloc;
  297. /* 4. initialize cdev */
  298. cdev_init(&(prGlueInfo->rBowInfo.cdev), &mt6620_ampc_fops);
  299. /* prGlueInfo->rBowInfo.cdev.owner = THIS_MODULE; */
  300. prGlueInfo->rBowInfo.cdev.ops = &mt6620_ampc_fops;
  301. /* 5. add character device */
  302. if (cdev_add(&(prGlueInfo->rBowInfo.cdev), prGlueInfo->rBowInfo.u4DeviceNumber, 1))
  303. goto fail_cdev_add;
  304. /* 6. in queue initialization */
  305. init_waitqueue_head(&(prGlueInfo->rBowInfo.outq));
  306. /* 7. finish */
  307. prGlueInfo->rBowInfo.fgIsRegistered = TRUE;
  308. return TRUE;
  309. fail_cdev_add:
  310. kfifo_free(&(prGlueInfo->rBowInfo.rKfifo));
  311. /* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */
  312. fail_kfifo_alloc:
  313. unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1);
  314. return FALSE;
  315. } /* end of glRegisterAmpc */
  316. /*----------------------------------------------------------------------------*/
  317. /*!
  318. * \brief Unregister character device for communicating with 802.11 PAL
  319. *
  320. * \param[in] prGlueInfo Pointer to glue info
  321. *
  322. * \return TRUE
  323. * FALSE
  324. */
  325. /*----------------------------------------------------------------------------*/
  326. BOOLEAN glUnregisterAmpc(IN P_GLUE_INFO_T prGlueInfo)
  327. {
  328. ASSERT(prGlueInfo);
  329. if (prGlueInfo->rBowInfo.fgIsRegistered == FALSE)
  330. return FALSE;
  331. prGlueInfo->rBowInfo.fgIsRegistered = FALSE;
  332. /* 1. free netdev if necessary */
  333. #if CFG_BOW_SEPARATE_DATA_PATH
  334. kalUninitBowDevice(prGlueInfo);
  335. #endif
  336. /* 2. removal of character device */
  337. cdev_del(&(prGlueInfo->rBowInfo.cdev));
  338. /* 3. free kfifo */
  339. /* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */
  340. kfifo_free(&(prGlueInfo->rBowInfo.rKfifo));
  341. /* prGlueInfo->rBowInfo.prKfifo = NULL; */
  342. /* prGlueInfo->rBowInfo.rKfifo = NULL; */
  343. /* 4. free device number */
  344. unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1);
  345. return TRUE;
  346. } /* end of glUnregisterAmpc */
  347. /*----------------------------------------------------------------------------*/
  348. /*!
  349. * \brief read handler for character device to communicate with 802.11 PAL
  350. *
  351. * \param[in]
  352. * \return
  353. * Follows Linux Character Device Interface
  354. *
  355. */
  356. /*----------------------------------------------------------------------------*/
  357. static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos)
  358. {
  359. UINT_8 aucBuffer[MAX_BUFFER_SIZE];
  360. ssize_t retval;
  361. P_GLUE_INFO_T prGlueInfo;
  362. prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
  363. ASSERT(prGlueInfo);
  364. if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
  365. return -EFAULT;
  366. /* size check */
  367. /* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */
  368. if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size)
  369. retval = size;
  370. else
  371. retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo));
  372. /* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */
  373. /* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */
  374. /* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */
  375. if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) {
  376. retval = -EIO;
  377. return retval;
  378. }
  379. if (copy_to_user(buf, aucBuffer, retval))
  380. retval = -EIO;
  381. return retval;
  382. }
  383. /*----------------------------------------------------------------------------*/
  384. /*!
  385. * \brief write handler for character device to communicate with 802.11 PAL
  386. *
  387. * \param[in]
  388. * \return
  389. * Follows Linux Character Device Interface
  390. *
  391. */
  392. /*----------------------------------------------------------------------------*/
  393. static ssize_t
  394. mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos)
  395. {
  396. #if CFG_BOW_TEST
  397. UINT_8 i;
  398. #endif
  399. UINT_8 aucBuffer[MAX_BUFFER_SIZE];
  400. P_AMPC_COMMAND prCmd;
  401. P_GLUE_INFO_T prGlueInfo;
  402. prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
  403. ASSERT(prGlueInfo);
  404. if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
  405. return -EFAULT;
  406. if (size > MAX_BUFFER_SIZE)
  407. return -EINVAL;
  408. else if (copy_from_user(aucBuffer, buf, size))
  409. return -EIO;
  410. #if CFG_BOW_TEST
  411. DBGLOG(BOW, EVENT, "AMP driver CMD buffer size : %d.\n", size);
  412. for (i = 0; i < MAX_BUFFER_SIZE; i++)
  413. DBGLOG(BOW, EVENT, "AMP write content : 0x%x.\n", aucBuffer[i]);
  414. DBGLOG(BOW, EVENT, "BoW CMD write.\n");
  415. #endif
  416. prCmd = (P_AMPC_COMMAND) aucBuffer;
  417. #if CFG_BOW_TEST
  418. DBGLOG(BOW, EVENT, "AMP write content payload length : %d.\n", prCmd->rHeader.u2PayloadLength);
  419. DBGLOG(BOW, EVENT, "AMP write content header length : %d.\n", sizeof(AMPC_COMMAND_HEADER_T));
  420. #endif
  421. /* size check */
  422. if (prCmd->rHeader.u2PayloadLength + sizeof(AMPC_COMMAND_HEADER_T) != size) {
  423. #if CFG_BOW_TEST
  424. DBGLOG(BOW, EVENT, "Wrong CMD total length.\n");
  425. #endif
  426. return -EINVAL;
  427. }
  428. if (wlanbowHandleCommand(prGlueInfo->prAdapter, prCmd) == WLAN_STATUS_SUCCESS)
  429. return size;
  430. else
  431. return -EINVAL;
  432. }
  433. /*----------------------------------------------------------------------------*/
  434. /*!
  435. * \brief ioctl handler for character device to communicate with 802.11 PAL
  436. *
  437. * \param[in]
  438. * \return
  439. * Follows Linux Character Device Interface
  440. *
  441. */
  442. /*----------------------------------------------------------------------------*/
  443. static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg)
  444. {
  445. int err = 0;
  446. P_GLUE_INFO_T prGlueInfo;
  447. prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
  448. ASSERT(prGlueInfo);
  449. if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
  450. return -EFAULT;
  451. /* permission check */
  452. if (_IOC_DIR(cmd) & _IOC_READ)
  453. err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
  454. else if (_IOC_DIR(cmd) & _IOC_WRITE)
  455. err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
  456. if (err)
  457. return -EFAULT;
  458. /* no ioctl is implemented yet */
  459. return 0;
  460. }
  461. /*----------------------------------------------------------------------------*/
  462. /*!
  463. * \brief ioctl handler for character device to communicate with 802.11 PAL
  464. *
  465. * \param[in]
  466. * \return
  467. * Follows Linux Character Device Interface
  468. *
  469. */
  470. /*----------------------------------------------------------------------------*/
  471. static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait)
  472. {
  473. unsigned int retval;
  474. P_GLUE_INFO_T prGlueInfo;
  475. prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
  476. ASSERT(prGlueInfo);
  477. if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
  478. return -EFAULT;
  479. poll_wait(filp, &prGlueInfo->rBowInfo.outq, wait);
  480. retval = (POLLOUT | POLLWRNORM); /* always accepts incoming command packets */
  481. /* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLOUT | POLLWRNORM, %x\n", retval)); */
  482. /* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) > 0) */
  483. if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) > 0) {
  484. retval |= (POLLIN | POLLRDNORM);
  485. /* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLIN | POLLRDNORM, %x\n", retval)); */
  486. }
  487. return retval;
  488. }
  489. /*----------------------------------------------------------------------------*/
  490. /*!
  491. * \brief open handler for character device to communicate with 802.11 PAL
  492. *
  493. * \param[in]
  494. * \return
  495. * Follows Linux Character Device Interface
  496. *
  497. */
  498. /*----------------------------------------------------------------------------*/
  499. static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp)
  500. {
  501. P_GLUE_INFO_T prGlueInfo;
  502. P_GL_BOW_INFO prBowInfo;
  503. prBowInfo = container_of(inodep->i_cdev, GL_BOW_INFO, cdev);
  504. ASSERT(prBowInfo);
  505. prGlueInfo = container_of(prBowInfo, GLUE_INFO_T, rBowInfo);
  506. ASSERT(prGlueInfo);
  507. /* set-up private data */
  508. filp->private_data = prGlueInfo;
  509. return 0;
  510. }
  511. /*----------------------------------------------------------------------------*/
  512. /*!
  513. * \brief close handler for character device to communicate with 802.11 PAL
  514. *
  515. * \param[in]
  516. * \return
  517. * Follows Linux Character Device Interface
  518. *
  519. */
  520. /*----------------------------------------------------------------------------*/
  521. static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp)
  522. {
  523. P_GLUE_INFO_T prGlueInfo;
  524. prGlueInfo = (P_GLUE_INFO_T) (filp->private_data);
  525. ASSERT(prGlueInfo);
  526. return 0;
  527. }
  528. /*----------------------------------------------------------------------------*/
  529. /*!
  530. * \brief to indicate event for Bluetooth over Wi-Fi
  531. *
  532. * \param[in]
  533. * prGlueInfo
  534. * prEvent
  535. * \return
  536. * none
  537. */
  538. /*----------------------------------------------------------------------------*/
  539. VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent)
  540. {
  541. size_t u4AvailSize, u4EventSize;
  542. ASSERT(prGlueInfo);
  543. ASSERT(prEvent);
  544. /* check device */
  545. if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT))
  546. return;
  547. /* u4AvailSize =
  548. GLUE_BOW_KFIFO_DEPTH - kfifo_len(prGlueInfo->rBowInfo.prKfifo);*/
  549. u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(&(prGlueInfo->rBowInfo.rKfifo));
  550. u4EventSize = prEvent->rHeader.u2PayloadLength + sizeof(AMPC_EVENT_HEADER_T);
  551. /* check kfifo availability */
  552. if (u4AvailSize < u4EventSize) {
  553. DBGLOG(BOW, EVENT, "[bow] no space for event: %zu/%zu\n", u4EventSize, u4AvailSize);
  554. return;
  555. }
  556. /* queue into kfifo */
  557. /* kfifo_put(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */
  558. /* kfifo_in(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */
  559. kfifo_in(&(prGlueInfo->rBowInfo.rKfifo), (PUINT_8) prEvent, u4EventSize);
  560. wake_up_interruptible(&(prGlueInfo->rBowInfo.outq));
  561. }
  562. /*----------------------------------------------------------------------------*/
  563. /*!
  564. * \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer
  565. *
  566. * \param[in]
  567. * prGlueInfo
  568. * rPeerAddr
  569. * \return
  570. * ENUM_BOW_DEVICE_STATE
  571. */
  572. /*----------------------------------------------------------------------------*/
  573. ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 aucPeerAddress[6])
  574. {
  575. UINT_8 i;
  576. ASSERT(prGlueInfo);
  577. #if CFG_BOW_TEST
  578. DBGLOG(BOW, EVENT, "kalGetBowState.\n");
  579. #endif
  580. for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
  581. if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) {
  582. #if CFG_BOW_TEST
  583. DBGLOG(BOW, EVENT, "kalGetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i,
  584. aucPeerAddress[0],
  585. aucPeerAddress[1],
  586. aucPeerAddress[2],
  587. aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]));
  588. DBGLOG(BOW, EVENT,
  589. "kalGetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i,
  590. prGlueInfo->rBowInfo.aeState[i]);
  591. #endif
  592. return prGlueInfo->rBowInfo.aeState[i];
  593. }
  594. }
  595. return BOW_DEVICE_STATE_DISCONNECTED;
  596. }
  597. /*----------------------------------------------------------------------------*/
  598. /*!
  599. * \brief to set Bluetooth-over-Wi-Fi state in glue layer
  600. *
  601. * \param[in]
  602. * prGlueInfo
  603. * eBowState
  604. * rPeerAddr
  605. * \return
  606. * none
  607. */
  608. /*----------------------------------------------------------------------------*/
  609. BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, IN UINT_8 aucPeerAddress[6])
  610. {
  611. UINT_8 i;
  612. ASSERT(prGlueInfo);
  613. #if CFG_BOW_TEST
  614. DBGLOG(BOW, EVENT, "kalSetBowState.\n");
  615. DBGLOG(BOW, EVENT, "kalSetBowState, prGlueInfo->rBowInfo.arPeerAddr, %x:%x:%x:%x:%x:%x.\n",
  616. prGlueInfo->rBowInfo.arPeerAddr[0],
  617. prGlueInfo->rBowInfo.arPeerAddr[1],
  618. prGlueInfo->rBowInfo.arPeerAddr[2],
  619. prGlueInfo->rBowInfo.arPeerAddr[3],
  620. prGlueInfo->rBowInfo.arPeerAddr[4], prGlueInfo->rBowInfo.arPeerAddr[5]));
  621. DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress, %x:%x:%x:%x:%x:%x.\n",
  622. aucPeerAddress[0],
  623. aucPeerAddress[1],
  624. aucPeerAddress[2], aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]);
  625. #endif
  626. for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
  627. if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) {
  628. prGlueInfo->rBowInfo.aeState[i] = eBowState;
  629. #if CFG_BOW_TEST
  630. DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i,
  631. aucPeerAddress[0],
  632. aucPeerAddress[1],
  633. aucPeerAddress[2],
  634. aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]));
  635. DBGLOG(BOW, EVENT,
  636. "kalSetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i,
  637. prGlueInfo->rBowInfo.aeState[i]);
  638. #endif
  639. return TRUE;
  640. }
  641. }
  642. return FALSE;
  643. }
  644. /*----------------------------------------------------------------------------*/
  645. /*!
  646. * \brief to retrieve Bluetooth-over-Wi-Fi global state
  647. *
  648. * \param[in]
  649. * prGlueInfo
  650. *
  651. * \return
  652. * BOW_DEVICE_STATE_DISCONNECTED
  653. * in case there is no BoW connection or
  654. * BoW connection under initialization
  655. *
  656. * BOW_DEVICE_STATE_STARTING
  657. * in case there is no BoW connection but
  658. * some BoW connection under initialization
  659. *
  660. * BOW_DEVICE_STATE_CONNECTED
  661. * in case there is any BoW connection available
  662. */
  663. /*----------------------------------------------------------------------------*/
  664. ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo)
  665. {
  666. UINT_32 i;
  667. ASSERT(prGlueInfo);
  668. /* Henry, can reduce this logic to indentify state change */
  669. for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
  670. if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_CONNECTED)
  671. return BOW_DEVICE_STATE_CONNECTED;
  672. }
  673. for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
  674. if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_STARTING)
  675. return BOW_DEVICE_STATE_STARTING;
  676. }
  677. return BOW_DEVICE_STATE_DISCONNECTED;
  678. }
  679. /*----------------------------------------------------------------------------*/
  680. /*!
  681. * \brief to retrieve Bluetooth-over-Wi-Fi operating frequency
  682. *
  683. * \param[in]
  684. * prGlueInfo
  685. *
  686. * \return
  687. * in unit of KHz
  688. */
  689. /*----------------------------------------------------------------------------*/
  690. UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo)
  691. {
  692. ASSERT(prGlueInfo);
  693. return prGlueInfo->rBowInfo.u4FreqInKHz;
  694. }
  695. /*----------------------------------------------------------------------------*/
  696. /*!
  697. * \brief to retrieve Bluetooth-over-Wi-Fi role
  698. *
  699. * \param[in]
  700. * prGlueInfo
  701. *
  702. * \return
  703. * 0: Responder
  704. * 1: Initiator
  705. */
  706. /*----------------------------------------------------------------------------*/
  707. UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr)
  708. {
  709. UINT_32 i;
  710. ASSERT(prGlueInfo);
  711. for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
  712. if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0)
  713. return prGlueInfo->rBowInfo.aucRole[i];
  714. }
  715. return 0;
  716. }
  717. /*----------------------------------------------------------------------------*/
  718. /*!
  719. * \brief to set Bluetooth-over-Wi-Fi role
  720. *
  721. * \param[in]
  722. * prGlueInfo
  723. * ucRole
  724. * 0: Responder
  725. * 1: Initiator
  726. * \return
  727. * none
  728. */
  729. /*----------------------------------------------------------------------------*/
  730. VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr)
  731. {
  732. UINT_32 i;
  733. ASSERT(prGlueInfo);
  734. ASSERT(ucRole <= 1);
  735. for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
  736. if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0)
  737. prGlueInfo->rBowInfo.aucRole[i] = ucRole; /* Henry, 0 : Responder, 1 : Initiator */
  738. }
  739. }
  740. /*----------------------------------------------------------------------------*/
  741. /*!
  742. * \brief to get available Bluetooth-over-Wi-Fi physical link number
  743. *
  744. * \param[in]
  745. * prGlueInfo
  746. * \return
  747. * UINT_32
  748. * how many physical links are aviailable
  749. */
  750. /*----------------------------------------------------------------------------*/
  751. UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo)
  752. {
  753. UINT_8 i;
  754. UINT_8 ucLinkCount = 0;
  755. ASSERT(prGlueInfo);
  756. for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) {
  757. if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_DISCONNECTED)
  758. ucLinkCount++;
  759. }
  760. #if 0 /* CFG_BOW_TEST */
  761. DBGLOG(BOW, EVENT, "kalGetBowAvailablePhysicalLinkCount, ucLinkCount, %c.\n", ucLinkCount);
  762. #endif
  763. return ucLinkCount;
  764. }
  765. #if CFG_BOW_SEPARATE_DATA_PATH
  766. /* Net Device Hooks */
  767. /*----------------------------------------------------------------------------*/
  768. /*!
  769. * \brief A function for net_device open (ifup)
  770. *
  771. * \param[in] prDev Pointer to struct net_device.
  772. *
  773. * \retval 0 The execution succeeds.
  774. * \retval < 0 The execution failed.
  775. */
  776. /*----------------------------------------------------------------------------*/
  777. static int bowOpen(IN struct net_device *prDev)
  778. {
  779. P_GLUE_INFO_T prGlueInfo = NULL;
  780. P_ADAPTER_T prAdapter = NULL;
  781. ASSERT(prDev);
  782. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  783. ASSERT(prGlueInfo);
  784. prAdapter = prGlueInfo->prAdapter;
  785. ASSERT(prAdapter);
  786. /* 2. carrier on & start TX queue */
  787. netif_carrier_on(prDev);
  788. netif_tx_start_all_queues(prDev);
  789. return 0; /* success */
  790. }
  791. /*----------------------------------------------------------------------------*/
  792. /*!
  793. * \brief A function for net_device stop (ifdown)
  794. *
  795. * \param[in] prDev Pointer to struct net_device.
  796. *
  797. * \retval 0 The execution succeeds.
  798. * \retval < 0 The execution failed.
  799. */
  800. /*----------------------------------------------------------------------------*/
  801. static int bowStop(IN struct net_device *prDev)
  802. {
  803. P_GLUE_INFO_T prGlueInfo = NULL;
  804. P_ADAPTER_T prAdapter = NULL;
  805. ASSERT(prDev);
  806. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  807. ASSERT(prGlueInfo);
  808. prAdapter = prGlueInfo->prAdapter;
  809. ASSERT(prAdapter);
  810. /* 1. stop TX queue */
  811. netif_tx_stop_all_queues(prDev);
  812. /* 2. turn of carrier */
  813. if (netif_carrier_ok(prDev))
  814. netif_carrier_off(prDev);
  815. return 0;
  816. };
  817. /*----------------------------------------------------------------------------*/
  818. /*!
  819. * \brief This function is TX entry point of NET DEVICE.
  820. *
  821. * \param[in] prSkb Pointer of the sk_buff to be sent
  822. * \param[in] prDev Pointer to struct net_device
  823. *
  824. * \retval NETDEV_TX_OK - on success.
  825. * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
  826. */
  827. /*----------------------------------------------------------------------------*/
  828. static int bowHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev)
  829. {
  830. P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
  831. P_QUE_ENTRY_T prQueueEntry = NULL;
  832. P_QUE_T prTxQueue = NULL;
  833. UINT_16 u2QueueIdx = 0;
  834. UINT_8 ucDSAP, ucSSAP, ucControl;
  835. UINT_8 aucOUI[3];
  836. PUINT_8 aucLookAheadBuf = NULL;
  837. #if CFG_BOW_TEST
  838. UINT_32 i;
  839. #endif
  840. GLUE_SPIN_LOCK_DECLARATION();
  841. ASSERT(prSkb);
  842. ASSERT(prDev);
  843. ASSERT(prGlueInfo);
  844. aucLookAheadBuf = prSkb->data;
  845. ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET];
  846. ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1];
  847. ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2];
  848. aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET];
  849. aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1];
  850. aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2];
  851. if (!(ucDSAP == ETH_LLC_DSAP_SNAP &&
  852. ucSSAP == ETH_LLC_SSAP_SNAP &&
  853. ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION &&
  854. aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 &&
  855. aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) {
  856. #if CFG_BOW_TEST
  857. DBGLOG(BOW, TRACE, "Invalid BOW packet, skip tx\n");
  858. #endif
  859. dev_kfree_skb(prSkb);
  860. return NETDEV_TX_OK;
  861. }
  862. if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) {
  863. DBGLOG(BOW, TRACE, "GLUE_FLAG_HALT skip tx\n");
  864. dev_kfree_skb(prSkb);
  865. return NETDEV_TX_OK;
  866. }
  867. prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
  868. prTxQueue = &prGlueInfo->rTxQueue;
  869. #if CFG_BOW_TEST
  870. DBGLOG(BOW, TRACE, "Tx sk_buff->len: %d\n", prSkb->len);
  871. DBGLOG(BOW, TRACE, "Tx sk_buff->data_len: %d\n", prSkb->data_len);
  872. DBGLOG(BOW, TRACE, "Tx sk_buff->data:\n");
  873. for (i = 0; i < prSkb->len; i++) {
  874. DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]);
  875. if ((i + 1) % 16 == 0)
  876. DBGLOG(BOW, TRACE, "\n");
  877. }
  878. DBGLOG(BOW, TRACE, "\n";
  879. #endif
  880. #if CFG_BOW_TEST
  881. /* g_u4CurrentSysTime = (OS_SYSTIME)kalGetTimeTick(; */
  882. g_u4CurrentSysTime = (OS_SYSTIME) jiffies_to_usecs(jiffies);
  883. i = g_u4CurrentSysTime - g_u4PrevSysTime;
  884. if ((i >> 10) > 0)
  885. i = 10;
  886. else
  887. i = i >> 7;
  888. g_arBowRevPalPacketTime[i]++;
  889. g_u4PrevSysTime = g_u4CurrentSysTime;
  890. #endif
  891. if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
  892. GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  893. QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
  894. GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
  895. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
  896. GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]);
  897. if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx] >=
  898. CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD)
  899. netif_stop_subqueue(prDev, u2QueueIdx);
  900. } else {
  901. GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
  902. }
  903. kalSetEvent(prGlueInfo);
  904. /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */
  905. return NETDEV_TX_OK;
  906. }
  907. /* callbacks for netdevice */
  908. static const struct net_device_ops bow_netdev_ops = {
  909. .ndo_open = bowOpen, .ndo_stop = bowStop, .ndo_start_xmit = bowHardStartXmit,};
  910. /*----------------------------------------------------------------------------*/
  911. /*!
  912. * \brief initialize net device for Bluetooth-over-Wi-Fi
  913. *
  914. * \param[in]
  915. * prGlueInfo
  916. * prDevName
  917. *
  918. * \return
  919. * TRUE
  920. * FALSE
  921. */
  922. /*----------------------------------------------------------------------------*/
  923. BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName)
  924. {
  925. P_ADAPTER_T prAdapter;
  926. P_GL_HIF_INFO_T prHif;
  927. PARAM_MAC_ADDRESS rMacAddr;
  928. ASSERT(prGlueInfo);
  929. ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE);
  930. prAdapter = prGlueInfo->prAdapter;
  931. ASSERT(prAdapter);
  932. prHif = &prGlueInfo->rHifInfo;
  933. ASSERT(prHif);
  934. if (prGlueInfo->rBowInfo.fgIsNetRegistered == FALSE) {
  935. prGlueInfo->rBowInfo.prDevHandler =
  936. alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM);
  937. if (!prGlueInfo->rBowInfo.prDevHandler)
  938. return FALSE;
  939. /* 1. setup netdev */
  940. /* 1.1 Point to shared glue structure */
  941. *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler)) = prGlueInfo;
  942. /* 1.2 fill hardware address */
  943. COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr);
  944. rMacAddr[0] |= 0x2;
  945. /* change to local administrated address */
  946. ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr);
  947. ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->perm_addr,
  948. prGlueInfo->rBowInfo.prDevHandler->dev_addr);
  949. /* 1.3 register callback functions */
  950. prGlueInfo->rBowInfo.prDevHandler->netdev_ops = &bow_netdev_ops;
  951. #if (MTK_WCN_HIF_SDIO == 0)
  952. SET_NETDEV_DEV(prGlueInfo->rBowInfo.prDevHandler, prHif->Dev);
  953. #endif
  954. register_netdev(prGlueInfo->rBowInfo.prDevHandler);
  955. /* 2. net device initialize */
  956. netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler);
  957. netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler);
  958. /* 3. finish */
  959. prGlueInfo->rBowInfo.fgIsNetRegistered = TRUE;
  960. }
  961. return TRUE;
  962. }
  963. /*----------------------------------------------------------------------------*/
  964. /*!
  965. * \brief uninitialize net device for Bluetooth-over-Wi-Fi
  966. *
  967. * \param[in]
  968. * prGlueInfo
  969. *
  970. * \return
  971. * TRUE
  972. * FALSE
  973. */
  974. /*----------------------------------------------------------------------------*/
  975. BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo)
  976. {
  977. ASSERT(prGlueInfo);
  978. /* ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); */
  979. if (prGlueInfo->rBowInfo.fgIsNetRegistered == TRUE) {
  980. prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE;
  981. if (netif_carrier_ok(prGlueInfo->rBowInfo.prDevHandler))
  982. netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler);
  983. netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler);
  984. /* netdevice unregistration & free */
  985. unregister_netdev(prGlueInfo->rBowInfo.prDevHandler);
  986. free_netdev(prGlueInfo->rBowInfo.prDevHandler);
  987. prGlueInfo->rBowInfo.prDevHandler = NULL;
  988. return TRUE;
  989. } else {
  990. return FALSE;
  991. }
  992. }
  993. #endif /* CFG_BOW_SEPARATE_DATA_PATH */
  994. #endif /* CFG_ENABLE_BT_OVER_WIFI */