rtk_coex.c 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068
  1. /*
  2. *
  3. * Realtek Bluetooth USB driver
  4. *
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/module.h>
  23. #include <linux/init.h>
  24. #include <linux/slab.h>
  25. #include <linux/types.h>
  26. #include <linux/sched.h>
  27. #include <linux/errno.h>
  28. #include <linux/skbuff.h>
  29. #include <linux/dcache.h>
  30. #include <linux/version.h>
  31. #include <net/sock.h>
  32. #include <net/bluetooth/bluetooth.h>
  33. #include <net/bluetooth/hci_core.h>
  34. #include <net/bluetooth/l2cap.h>
  35. #include "rtk_coex.h"
  36. /* Software coex message can be sent to and receive from WiFi driver by
  37. * UDP socket or exported symbol */
  38. /* #define RTK_COEX_OVER_SYMBOL */
  39. #if BTRTL_HCI_IF == BTRTL_HCIUSB
  40. #include <linux/usb.h>
  41. #include "rtk_bt.h"
  42. #undef RTKBT_DBG
  43. #undef RTKBT_INFO
  44. #undef RTKBT_WARN
  45. #undef RTKBT_ERR
  46. #elif BTRTL_HCI_IF == BTRTL_HCIUART
  47. /* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
  48. #define HCI_VERSION_CODE LINUX_VERSION_CODE
  49. #else
  50. #error "Please set type of HCI interface"
  51. #endif
  52. #define RTK_VERSION "1.2"
  53. #define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
  54. #define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
  55. #define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "\n", ## arg)
  56. #define RTKBT_ERR(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "\n", ## arg)
  57. static struct rtl_coex_struct btrtl_coex;
  58. #ifdef RTB_SOFTWARE_MAILBOX
  59. #ifdef RTK_COEX_OVER_SYMBOL
  60. static struct sk_buff_head rtw_q;
  61. static struct workqueue_struct *rtw_wq;
  62. static struct work_struct rtw_work;
  63. static u8 rtw_coex_on;
  64. #endif
  65. #endif
  66. #define is_profile_connected(profile) ((btrtl_coex.profile_bitmap & BIT(profile)) > 0)
  67. #define is_profile_busy(profile) ((btrtl_coex.profile_status & BIT(profile)) > 0)
  68. #ifdef RTB_SOFTWARE_MAILBOX
  69. static void rtk_handle_event_from_wifi(uint8_t * msg);
  70. #endif
  71. static int rtl_alloc_buff(struct rtl_coex_struct *coex)
  72. {
  73. struct rtl_hci_ev *ev;
  74. struct rtl_l2_buff *l2;
  75. int i;
  76. int order;
  77. unsigned long addr;
  78. unsigned long addr2;
  79. int ev_size;
  80. int l2_size;
  81. int n;
  82. spin_lock_init(&coex->buff_lock);
  83. INIT_LIST_HEAD(&coex->ev_used_list);
  84. INIT_LIST_HEAD(&coex->ev_free_list);
  85. INIT_LIST_HEAD(&coex->l2_used_list);
  86. INIT_LIST_HEAD(&coex->l2_free_list);
  87. n = NUM_RTL_HCI_EV * sizeof(struct rtl_hci_ev);
  88. ev_size = ALIGN(n, sizeof(unsigned long));
  89. n = L2_MAX_PKTS * sizeof(struct rtl_l2_buff);
  90. l2_size = ALIGN(n, sizeof(unsigned long));
  91. RTKBT_DBG("alloc buffers %d, %d for ev and l2", ev_size, l2_size);
  92. order = get_order(ev_size + l2_size);
  93. addr = __get_free_pages(GFP_KERNEL, order);
  94. if (!addr) {
  95. RTKBT_ERR("failed to alloc buffers for ev and l2.");
  96. return -ENOMEM;
  97. }
  98. memset((void *)addr, 0, ev_size + l2_size);
  99. coex->pages_addr = addr;
  100. coex->buff_size = ev_size + l2_size;
  101. ev = (struct rtl_hci_ev *)addr;
  102. for (i = 0; i < NUM_RTL_HCI_EV; i++) {
  103. list_add_tail(&ev->list, &coex->ev_free_list);
  104. ev++;
  105. }
  106. addr2 = addr + ev_size;
  107. l2 = (struct rtl_l2_buff *)addr2;
  108. for (i = 0; i < L2_MAX_PKTS; i++) {
  109. list_add_tail(&l2->list, &coex->l2_free_list);
  110. l2++;
  111. }
  112. return 0;
  113. }
  114. static void rtl_free_buff(struct rtl_coex_struct *coex)
  115. {
  116. struct rtl_hci_ev *ev;
  117. struct rtl_l2_buff *l2;
  118. unsigned long flags;
  119. spin_lock_irqsave(&coex->buff_lock, flags);
  120. while (!list_empty(&coex->ev_used_list)) {
  121. ev = list_entry(coex->ev_used_list.next, struct rtl_hci_ev,
  122. list);
  123. list_del(&ev->list);
  124. }
  125. while (!list_empty(&coex->ev_free_list)) {
  126. ev = list_entry(coex->ev_free_list.next, struct rtl_hci_ev,
  127. list);
  128. list_del(&ev->list);
  129. }
  130. while (!list_empty(&coex->l2_used_list)) {
  131. l2 = list_entry(coex->l2_used_list.next, struct rtl_l2_buff,
  132. list);
  133. list_del(&l2->list);
  134. }
  135. while (!list_empty(&coex->l2_free_list)) {
  136. l2 = list_entry(coex->l2_free_list.next, struct rtl_l2_buff,
  137. list);
  138. list_del(&l2->list);
  139. }
  140. spin_unlock_irqrestore(&coex->buff_lock, flags);
  141. if (coex->buff_size > 0) {
  142. free_pages(coex->pages_addr, get_order(coex->buff_size));
  143. coex->pages_addr = 0;
  144. coex->buff_size = 0;
  145. }
  146. }
  147. static struct rtl_hci_ev *rtl_ev_node_get(struct rtl_coex_struct *coex)
  148. {
  149. struct rtl_hci_ev *ev;
  150. unsigned long flags;
  151. if (!coex->buff_size)
  152. return NULL;
  153. spin_lock_irqsave(&coex->buff_lock, flags);
  154. if (!list_empty(&coex->ev_free_list)) {
  155. ev = list_entry(coex->ev_free_list.next, struct rtl_hci_ev,
  156. list);
  157. list_del(&ev->list);
  158. } else
  159. ev = NULL;
  160. spin_unlock_irqrestore(&coex->buff_lock, flags);
  161. return ev;
  162. }
  163. static int rtl_ev_node_to_used(struct rtl_coex_struct *coex,
  164. struct rtl_hci_ev *ev)
  165. {
  166. unsigned long flags;
  167. spin_lock_irqsave(&coex->buff_lock, flags);
  168. list_add_tail(&ev->list, &coex->ev_used_list);
  169. spin_unlock_irqrestore(&coex->buff_lock, flags);
  170. return 0;
  171. }
  172. static struct rtl_l2_buff *rtl_l2_node_get(struct rtl_coex_struct *coex)
  173. {
  174. struct rtl_l2_buff *l2;
  175. unsigned long flags;
  176. if (!coex->buff_size)
  177. return NULL;
  178. spin_lock_irqsave(&coex->buff_lock, flags);
  179. if(!list_empty(&coex->l2_free_list)) {
  180. l2 = list_entry(coex->l2_free_list.next, struct rtl_l2_buff,
  181. list);
  182. list_del(&l2->list);
  183. } else
  184. l2 = NULL;
  185. spin_unlock_irqrestore(&coex->buff_lock, flags);
  186. return l2;
  187. }
  188. static int rtl_l2_node_to_used(struct rtl_coex_struct *coex,
  189. struct rtl_l2_buff *l2)
  190. {
  191. unsigned long flags;
  192. spin_lock_irqsave(&coex->buff_lock, flags);
  193. list_add_tail(&l2->list, &coex->l2_used_list);
  194. spin_unlock_irqrestore(&coex->buff_lock, flags);
  195. return 0;
  196. }
  197. static int8_t psm_to_profile_index(uint16_t psm)
  198. {
  199. switch (psm) {
  200. case PSM_AVCTP:
  201. case PSM_SDP:
  202. return -1; //ignore
  203. case PSM_HID:
  204. case PSM_HID_INT:
  205. return profile_hid;
  206. case PSM_AVDTP:
  207. return profile_a2dp;
  208. case PSM_PAN:
  209. case PSM_OPP:
  210. case PSM_FTP:
  211. case PSM_BIP:
  212. case PSM_RFCOMM:
  213. return profile_pan;
  214. default:
  215. return profile_pan;
  216. }
  217. }
  218. static rtk_prof_info *find_by_psm(u16 psm)
  219. {
  220. struct list_head *head = &btrtl_coex.profile_list;
  221. struct list_head *iter = NULL;
  222. struct list_head *temp = NULL;
  223. rtk_prof_info *desc = NULL;
  224. list_for_each_safe(iter, temp, head) {
  225. desc = list_entry(iter, rtk_prof_info, list);
  226. if (desc->psm == psm)
  227. return desc;
  228. }
  229. return NULL;
  230. }
  231. static void rtk_check_setup_timer(int8_t profile_index)
  232. {
  233. if (profile_index == profile_a2dp) {
  234. btrtl_coex.a2dp_packet_count = 0;
  235. btrtl_coex.a2dp_count_timer.expires =
  236. jiffies + msecs_to_jiffies(1000);
  237. mod_timer(&btrtl_coex.a2dp_count_timer,
  238. btrtl_coex.a2dp_count_timer.expires);
  239. }
  240. if (profile_index == profile_pan) {
  241. btrtl_coex.pan_packet_count = 0;
  242. btrtl_coex.pan_count_timer.expires =
  243. jiffies + msecs_to_jiffies(1000);
  244. mod_timer(&btrtl_coex.pan_count_timer,
  245. btrtl_coex.pan_count_timer.expires);
  246. }
  247. /* hogp & voice share one timer now */
  248. if ((profile_index == profile_hogp) || (profile_index == profile_voice)) {
  249. if ((0 == btrtl_coex.profile_refcount[profile_hogp])
  250. && (0 == btrtl_coex.profile_refcount[profile_voice])) {
  251. btrtl_coex.hogp_packet_count = 0;
  252. btrtl_coex.voice_packet_count = 0;
  253. btrtl_coex.hogp_count_timer.expires =
  254. jiffies + msecs_to_jiffies(1000);
  255. mod_timer(&btrtl_coex.hogp_count_timer,
  256. btrtl_coex.hogp_count_timer.expires);
  257. }
  258. }
  259. }
  260. static void rtk_check_del_timer(int8_t profile_index)
  261. {
  262. if (profile_a2dp == profile_index) {
  263. btrtl_coex.a2dp_packet_count = 0;
  264. del_timer_sync(&btrtl_coex.a2dp_count_timer);
  265. }
  266. if (profile_pan == profile_index) {
  267. btrtl_coex.pan_packet_count = 0;
  268. del_timer_sync(&btrtl_coex.pan_count_timer);
  269. }
  270. if (profile_hogp == profile_index) {
  271. btrtl_coex.hogp_packet_count = 0;
  272. if (btrtl_coex.profile_refcount[profile_voice] == 0) {
  273. del_timer_sync(&btrtl_coex.hogp_count_timer);
  274. }
  275. }
  276. if (profile_voice == profile_index) {
  277. btrtl_coex.voice_packet_count = 0;
  278. if (btrtl_coex.profile_refcount[profile_hogp] == 0) {
  279. del_timer_sync(&btrtl_coex.hogp_count_timer);
  280. }
  281. }
  282. }
  283. static rtk_conn_prof *find_connection_by_handle(struct rtl_coex_struct * coex,
  284. uint16_t handle)
  285. {
  286. struct list_head *head = &coex->conn_hash;
  287. struct list_head *iter = NULL, *temp = NULL;
  288. rtk_conn_prof *desc = NULL;
  289. list_for_each_safe(iter, temp, head) {
  290. desc = list_entry(iter, rtk_conn_prof, list);
  291. if ((handle & 0xEFF) == desc->handle) {
  292. return desc;
  293. }
  294. }
  295. return NULL;
  296. }
  297. static rtk_conn_prof *allocate_connection_by_handle(uint16_t handle)
  298. {
  299. rtk_conn_prof *phci_conn = NULL;
  300. phci_conn = kmalloc(sizeof(rtk_conn_prof), GFP_ATOMIC);
  301. if (phci_conn)
  302. phci_conn->handle = handle;
  303. return phci_conn;
  304. }
  305. static void init_connection_hash(struct rtl_coex_struct * coex)
  306. {
  307. struct list_head *head = &coex->conn_hash;
  308. INIT_LIST_HEAD(head);
  309. }
  310. static void add_connection_to_hash(struct rtl_coex_struct * coex,
  311. rtk_conn_prof * desc)
  312. {
  313. struct list_head *head = &coex->conn_hash;
  314. list_add_tail(&desc->list, head);
  315. }
  316. static void delete_connection_from_hash(rtk_conn_prof * desc)
  317. {
  318. if (desc) {
  319. list_del(&desc->list);
  320. kfree(desc);
  321. }
  322. }
  323. static void flush_connection_hash(struct rtl_coex_struct * coex)
  324. {
  325. struct list_head *head = &coex->conn_hash;
  326. struct list_head *iter = NULL, *temp = NULL;
  327. rtk_conn_prof *desc = NULL;
  328. list_for_each_safe(iter, temp, head) {
  329. desc = list_entry(iter, rtk_conn_prof, list);
  330. if (desc) {
  331. list_del(&desc->list);
  332. kfree(desc);
  333. }
  334. }
  335. //INIT_LIST_HEAD(head);
  336. }
  337. static void init_profile_hash(struct rtl_coex_struct * coex)
  338. {
  339. struct list_head *head = &coex->profile_list;
  340. INIT_LIST_HEAD(head);
  341. }
  342. static uint8_t list_allocate_add(uint16_t handle, uint16_t psm,
  343. int8_t profile_index, uint16_t dcid,
  344. uint16_t scid)
  345. {
  346. rtk_prof_info *pprof_info = NULL;
  347. if (profile_index < 0) {
  348. RTKBT_ERR("PSM 0x%x do not need parse", psm);
  349. return FALSE;
  350. }
  351. pprof_info = kmalloc(sizeof(rtk_prof_info), GFP_ATOMIC);
  352. if (NULL == pprof_info) {
  353. RTKBT_ERR("list_allocate_add: allocate error");
  354. return FALSE;
  355. }
  356. /* Check if it is the second l2cap connection for a2dp
  357. * a2dp signal channel will be created first than media channel.
  358. */
  359. if (psm == PSM_AVDTP) {
  360. rtk_prof_info *pinfo = find_by_psm(psm);
  361. if (!pinfo) {
  362. pprof_info->flags = A2DP_SIGNAL;
  363. RTKBT_INFO("%s: Add a2dp signal channel", __func__);
  364. } else {
  365. pprof_info->flags = A2DP_MEDIA;
  366. RTKBT_INFO("%s: Add a2dp media channel", __func__);
  367. }
  368. }
  369. pprof_info->handle = handle;
  370. pprof_info->psm = psm;
  371. pprof_info->scid = scid;
  372. pprof_info->dcid = dcid;
  373. pprof_info->profile_index = profile_index;
  374. list_add_tail(&(pprof_info->list), &(btrtl_coex.profile_list));
  375. return TRUE;
  376. }
  377. static void delete_profile_from_hash(rtk_prof_info * desc)
  378. {
  379. RTKBT_DBG("Delete profile: hndl 0x%04x, psm 0x%04x, dcid 0x%04x, "
  380. "scid 0x%04x", desc->handle, desc->psm, desc->dcid,
  381. desc->scid);
  382. if (desc) {
  383. list_del(&desc->list);
  384. kfree(desc);
  385. desc = NULL;
  386. }
  387. }
  388. static void flush_profile_hash(struct rtl_coex_struct * coex)
  389. {
  390. struct list_head *head = &coex->profile_list;
  391. struct list_head *iter = NULL, *temp = NULL;
  392. rtk_prof_info *desc = NULL;
  393. spin_lock(&btrtl_coex.spin_lock_profile);
  394. list_for_each_safe(iter, temp, head) {
  395. desc = list_entry(iter, rtk_prof_info, list);
  396. delete_profile_from_hash(desc);
  397. }
  398. //INIT_LIST_HEAD(head);
  399. spin_unlock(&btrtl_coex.spin_lock_profile);
  400. }
  401. static rtk_prof_info *find_profile_by_handle_scid(struct rtl_coex_struct *
  402. coex, uint16_t handle,
  403. uint16_t scid)
  404. {
  405. struct list_head *head = &coex->profile_list;
  406. struct list_head *iter = NULL, *temp = NULL;
  407. rtk_prof_info *desc = NULL;
  408. list_for_each_safe(iter, temp, head) {
  409. desc = list_entry(iter, rtk_prof_info, list);
  410. if (((handle & 0xFFF) == desc->handle) && (scid == desc->scid)) {
  411. return desc;
  412. }
  413. }
  414. return NULL;
  415. }
  416. static rtk_prof_info *find_profile_by_handle_dcid(struct rtl_coex_struct *
  417. coex, uint16_t handle,
  418. uint16_t dcid)
  419. {
  420. struct list_head *head = &coex->profile_list;
  421. struct list_head *iter = NULL, *temp = NULL;
  422. rtk_prof_info *desc = NULL;
  423. list_for_each_safe(iter, temp, head) {
  424. desc = list_entry(iter, rtk_prof_info, list);
  425. if (((handle & 0xFFF) == desc->handle) && (dcid == desc->dcid)) {
  426. return desc;
  427. }
  428. }
  429. return NULL;
  430. }
  431. static rtk_prof_info *find_profile_by_handle_dcid_scid(struct rtl_coex_struct
  432. * coex, uint16_t handle,
  433. uint16_t dcid,
  434. uint16_t scid)
  435. {
  436. struct list_head *head = &coex->profile_list;
  437. struct list_head *iter = NULL, *temp = NULL;
  438. rtk_prof_info *desc = NULL;
  439. list_for_each_safe(iter, temp, head) {
  440. desc = list_entry(iter, rtk_prof_info, list);
  441. if (((handle & 0xFFF) == desc->handle) && (dcid == desc->dcid)
  442. && (scid == desc->scid)) {
  443. return desc;
  444. }
  445. }
  446. return NULL;
  447. }
  448. static void rtk_vendor_cmd_to_fw(uint16_t opcode, uint8_t parameter_len,
  449. uint8_t * parameter)
  450. {
  451. int len = HCI_CMD_PREAMBLE_SIZE + parameter_len;
  452. uint8_t *p;
  453. struct sk_buff *skb;
  454. struct hci_dev *hdev = btrtl_coex.hdev;
  455. if (!hdev) {
  456. RTKBT_ERR("No HCI device");
  457. return;
  458. } else if (!test_bit(HCI_UP, &hdev->flags)) {
  459. RTKBT_WARN("HCI device is down");
  460. return;
  461. }
  462. skb = bt_skb_alloc(len, GFP_ATOMIC);
  463. if (!skb) {
  464. RTKBT_DBG("there is no room for cmd 0x%x", opcode);
  465. return;
  466. }
  467. p = (uint8_t *) skb_put(skb, HCI_CMD_PREAMBLE_SIZE);
  468. UINT16_TO_STREAM(p, opcode);
  469. *p++ = parameter_len;
  470. if (parameter_len)
  471. memcpy(skb_put(skb, parameter_len), parameter, parameter_len);
  472. bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
  473. #if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
  474. #if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
  475. bt_cb(skb)->opcode = opcode;
  476. #else
  477. bt_cb(skb)->hci.opcode = opcode;
  478. #endif
  479. #endif
  480. /* Stand-alone HCI commands must be flagged as
  481. * single-command requests.
  482. */
  483. #if HCI_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  484. #if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
  485. bt_cb(skb)->req.start = true;
  486. #else
  487. #if HCI_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
  488. bt_cb(skb)->hci.req_start = true;
  489. #else
  490. bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
  491. #endif
  492. #endif /* 4.4.0 */
  493. #endif /* 3.10.0 */
  494. RTKBT_DBG("%s: opcode 0x%x", __func__, opcode);
  495. /* It is harmless if set skb->dev twice. The dev will be used in
  496. * btusb_send_frame() after or equal to kernel/hci 3.13.0,
  497. * the hdev will not come from skb->dev. */
  498. #if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
  499. skb->dev = (void *)btrtl_coex.hdev;
  500. #endif
  501. /* Put the skb to the global hdev->cmd_q */
  502. skb_queue_tail(&hdev->cmd_q, skb);
  503. #if HCI_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
  504. tasklet_schedule(&hdev->cmd_task);
  505. #else
  506. queue_work(hdev->workqueue, &hdev->cmd_work);
  507. #endif
  508. return;
  509. }
  510. static void rtk_notify_profileinfo_to_fw(void)
  511. {
  512. struct list_head *head = NULL;
  513. struct list_head *iter = NULL;
  514. struct list_head *temp = NULL;
  515. rtk_conn_prof *hci_conn = NULL;
  516. uint8_t handle_number = 0;
  517. uint32_t buffer_size = 0;
  518. uint8_t *p_buf = NULL;
  519. uint8_t *p = NULL;
  520. head = &btrtl_coex.conn_hash;
  521. list_for_each_safe(iter, temp, head) {
  522. hci_conn = list_entry(iter, rtk_conn_prof, list);
  523. if (hci_conn && hci_conn->profile_bitmap)
  524. handle_number++;
  525. }
  526. buffer_size = 1 + handle_number * 3 + 1;
  527. p_buf = kmalloc(buffer_size, GFP_ATOMIC);
  528. if (NULL == p_buf) {
  529. RTKBT_ERR("%s: alloc error", __func__);
  530. return;
  531. }
  532. p = p_buf;
  533. RTKBT_DBG("%s: BufferSize %u", __func__, buffer_size);
  534. *p++ = handle_number;
  535. RTKBT_DBG("%s: NumberOfHandles %u", __func__, handle_number);
  536. head = &btrtl_coex.conn_hash;
  537. list_for_each(iter, head) {
  538. hci_conn = list_entry(iter, rtk_conn_prof, list);
  539. if (hci_conn && hci_conn->profile_bitmap) {
  540. UINT16_TO_STREAM(p, hci_conn->handle);
  541. RTKBT_DBG("%s: handle 0x%04x", __func__,
  542. hci_conn->handle);
  543. *p++ = hci_conn->profile_bitmap;
  544. RTKBT_DBG("%s: profile_bitmap 0x%02x", __func__,
  545. hci_conn->profile_bitmap);
  546. handle_number--;
  547. }
  548. if (0 == handle_number)
  549. break;
  550. }
  551. *p++ = btrtl_coex.profile_status;
  552. RTKBT_DBG("%s: profile_status 0x%02x", __func__,
  553. btrtl_coex.profile_status);
  554. rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_PROFILE_REPORT_COMMAND, buffer_size,
  555. p_buf);
  556. kfree(p_buf);
  557. return;
  558. }
  559. static void update_profile_state(uint8_t profile_index, uint8_t is_busy)
  560. {
  561. uint8_t need_update = FALSE;
  562. if ((btrtl_coex.profile_bitmap & BIT(profile_index)) == 0) {
  563. RTKBT_ERR("%s: : ERROR!!! profile(Index: %x) does not exist",
  564. __func__, profile_index);
  565. return;
  566. }
  567. if (is_busy) {
  568. if ((btrtl_coex.profile_status & BIT(profile_index)) == 0) {
  569. need_update = TRUE;
  570. btrtl_coex.profile_status |= BIT(profile_index);
  571. }
  572. } else {
  573. if ((btrtl_coex.profile_status & BIT(profile_index)) > 0) {
  574. need_update = TRUE;
  575. btrtl_coex.profile_status &= ~(BIT(profile_index));
  576. }
  577. }
  578. if (need_update) {
  579. RTKBT_DBG("%s: btrtl_coex.profie_bitmap = %x",
  580. __func__, btrtl_coex.profile_bitmap);
  581. RTKBT_DBG("%s: btrtl_coex.profile_status = %x",
  582. __func__, btrtl_coex.profile_status);
  583. rtk_notify_profileinfo_to_fw();
  584. }
  585. }
  586. static void update_profile_connection(rtk_conn_prof * phci_conn,
  587. int8_t profile_index, uint8_t is_add)
  588. {
  589. uint8_t need_update = FALSE;
  590. uint8_t kk;
  591. RTKBT_DBG("%s: is_add %d, profile_index %x", __func__,
  592. is_add, profile_index);
  593. if (profile_index < 0)
  594. return;
  595. if (is_add) {
  596. if (btrtl_coex.profile_refcount[profile_index] == 0) {
  597. need_update = TRUE;
  598. btrtl_coex.profile_bitmap |= BIT(profile_index);
  599. /* SCO is always busy */
  600. if (profile_index == profile_sco)
  601. btrtl_coex.profile_status |=
  602. BIT(profile_index);
  603. rtk_check_setup_timer(profile_index);
  604. }
  605. btrtl_coex.profile_refcount[profile_index]++;
  606. if (0 == phci_conn->profile_refcount[profile_index]) {
  607. need_update = TRUE;
  608. phci_conn->profile_bitmap |= BIT(profile_index);
  609. }
  610. phci_conn->profile_refcount[profile_index]++;
  611. } else {
  612. if (!btrtl_coex.profile_refcount[profile_index]) {
  613. RTKBT_WARN("profile %u refcount is already zero",
  614. profile_index);
  615. return;
  616. }
  617. btrtl_coex.profile_refcount[profile_index]--;
  618. RTKBT_DBG("%s: btrtl_coex.profile_refcount[%x] = %x",
  619. __func__, profile_index,
  620. btrtl_coex.profile_refcount[profile_index]);
  621. if (btrtl_coex.profile_refcount[profile_index] == 0) {
  622. need_update = TRUE;
  623. btrtl_coex.profile_bitmap &= ~(BIT(profile_index));
  624. /* if profile does not exist, status is meaningless */
  625. btrtl_coex.profile_status &= ~(BIT(profile_index));
  626. rtk_check_del_timer(profile_index);
  627. }
  628. phci_conn->profile_refcount[profile_index]--;
  629. if (0 == phci_conn->profile_refcount[profile_index]) {
  630. need_update = TRUE;
  631. phci_conn->profile_bitmap &= ~(BIT(profile_index));
  632. /* clear profile_hid_interval if need */
  633. if ((profile_hid == profile_index)
  634. && (phci_conn->
  635. profile_bitmap & (BIT(profile_hid_interval)))) {
  636. phci_conn->profile_bitmap &=
  637. ~(BIT(profile_hid_interval));
  638. btrtl_coex.
  639. profile_refcount[profile_hid_interval]--;
  640. }
  641. }
  642. }
  643. RTKBT_DBG("%s: btrtl_coex.profile_bitmap 0x%02x", __func__,
  644. btrtl_coex.profile_bitmap);
  645. for (kk = 0; kk < 8; kk++)
  646. RTKBT_DBG("%s: btrtl_coex.profile_refcount[%d] = %d",
  647. __func__, kk,
  648. btrtl_coex.profile_refcount[kk]);
  649. if (need_update)
  650. rtk_notify_profileinfo_to_fw();
  651. }
  652. static void update_hid_active_state(uint16_t handle, uint16_t interval)
  653. {
  654. uint8_t need_update = 0;
  655. rtk_conn_prof *phci_conn =
  656. find_connection_by_handle(&btrtl_coex, handle);
  657. if (phci_conn == NULL)
  658. return;
  659. RTKBT_DBG("%s: handle 0x%04x, interval %u", __func__, handle, interval);
  660. if (((phci_conn->profile_bitmap) & (BIT(profile_hid))) == 0) {
  661. RTKBT_DBG("HID not connected, nothing to be down");
  662. return;
  663. }
  664. if (interval < 60) {
  665. if ((phci_conn->profile_bitmap & (BIT(profile_hid_interval))) ==
  666. 0) {
  667. need_update = 1;
  668. phci_conn->profile_bitmap |= BIT(profile_hid_interval);
  669. btrtl_coex.profile_refcount[profile_hid_interval]++;
  670. if (btrtl_coex.
  671. profile_refcount[profile_hid_interval] == 1)
  672. btrtl_coex.profile_status |=
  673. BIT(profile_hid);
  674. }
  675. } else {
  676. if ((phci_conn->profile_bitmap & (BIT(profile_hid_interval)))) {
  677. need_update = 1;
  678. phci_conn->profile_bitmap &=
  679. ~(BIT(profile_hid_interval));
  680. btrtl_coex.profile_refcount[profile_hid_interval]--;
  681. if (btrtl_coex.
  682. profile_refcount[profile_hid_interval] == 0)
  683. btrtl_coex.profile_status &=
  684. ~(BIT(profile_hid));
  685. }
  686. }
  687. if (need_update)
  688. rtk_notify_profileinfo_to_fw();
  689. }
  690. static uint8_t handle_l2cap_con_req(uint16_t handle, uint16_t psm,
  691. uint16_t scid, uint8_t direction)
  692. {
  693. uint8_t status = FALSE;
  694. rtk_prof_info *prof_info = NULL;
  695. int8_t profile_index = psm_to_profile_index(psm);
  696. if (profile_index < 0) {
  697. RTKBT_DBG("PSM(0x%04x) do not need parse", psm);
  698. return status;
  699. }
  700. spin_lock(&btrtl_coex.spin_lock_profile);
  701. if (direction) //1: out
  702. prof_info =
  703. find_profile_by_handle_scid(&btrtl_coex, handle, scid);
  704. else // 0:in
  705. prof_info =
  706. find_profile_by_handle_dcid(&btrtl_coex, handle, scid);
  707. if (prof_info) {
  708. RTKBT_DBG("%s: this profile is already exist!", __func__);
  709. spin_unlock(&btrtl_coex.spin_lock_profile);
  710. return status;
  711. }
  712. if (direction) //1: out
  713. status = list_allocate_add(handle, psm, profile_index, 0, scid);
  714. else // 0:in
  715. status = list_allocate_add(handle, psm, profile_index, scid, 0);
  716. spin_unlock(&btrtl_coex.spin_lock_profile);
  717. if (!status)
  718. RTKBT_ERR("%s: list_allocate_add failed!", __func__);
  719. return status;
  720. }
  721. static uint8_t handle_l2cap_con_rsp(uint16_t handle, uint16_t dcid,
  722. uint16_t scid, uint8_t direction,
  723. uint8_t result)
  724. {
  725. rtk_prof_info *prof_info = NULL;
  726. rtk_conn_prof *phci_conn = NULL;
  727. spin_lock(&btrtl_coex.spin_lock_profile);
  728. if (!direction) //0, in
  729. prof_info =
  730. find_profile_by_handle_scid(&btrtl_coex, handle, scid);
  731. else //1, out
  732. prof_info =
  733. find_profile_by_handle_dcid(&btrtl_coex, handle, scid);
  734. if (!prof_info) {
  735. //RTKBT_DBG("handle_l2cap_con_rsp: prof_info Not Find!!");
  736. spin_unlock(&btrtl_coex.spin_lock_profile);
  737. return FALSE;
  738. }
  739. if (!result) { //success
  740. RTKBT_DBG("l2cap connection success, update connection");
  741. if (!direction) //0, in
  742. prof_info->dcid = dcid;
  743. else //1, out
  744. prof_info->scid = dcid;
  745. phci_conn = find_connection_by_handle(&btrtl_coex, handle);
  746. if (phci_conn)
  747. update_profile_connection(phci_conn,
  748. prof_info->profile_index,
  749. TRUE);
  750. }
  751. spin_unlock(&btrtl_coex.spin_lock_profile);
  752. return TRUE;
  753. }
  754. static uint8_t handle_l2cap_discon_req(uint16_t handle, uint16_t dcid,
  755. uint16_t scid, uint8_t direction)
  756. {
  757. rtk_prof_info *prof_info = NULL;
  758. rtk_conn_prof *phci_conn = NULL;
  759. RTKBT_DBG("%s: handle 0x%04x, dcid 0x%04x, scid 0x%04x, dir %u",
  760. __func__, handle, dcid, scid, direction);
  761. spin_lock(&btrtl_coex.spin_lock_profile);
  762. if (!direction) //0: in
  763. prof_info =
  764. find_profile_by_handle_dcid_scid(&btrtl_coex, handle,
  765. scid, dcid);
  766. else //1: out
  767. prof_info =
  768. find_profile_by_handle_dcid_scid(&btrtl_coex, handle,
  769. dcid, scid);
  770. if (!prof_info) {
  771. //LogMsg("handle_l2cap_discon_req: prof_info Not Find!");
  772. spin_unlock(&btrtl_coex.spin_lock_profile);
  773. return 0;
  774. }
  775. phci_conn = find_connection_by_handle(&btrtl_coex, handle);
  776. if (!phci_conn) {
  777. spin_unlock(&btrtl_coex.spin_lock_profile);
  778. return 0;
  779. }
  780. update_profile_connection(phci_conn, prof_info->profile_index, FALSE);
  781. if (prof_info->profile_index == profile_a2dp &&
  782. (phci_conn->profile_bitmap & BIT(profile_sink)))
  783. update_profile_connection(phci_conn, profile_sink, FALSE);
  784. delete_profile_from_hash(prof_info);
  785. spin_unlock(&btrtl_coex.spin_lock_profile);
  786. return 1;
  787. }
  788. static const char sample_freqs[4][8] = {
  789. "16", "32", "44.1", "48"
  790. };
  791. static const uint8_t sbc_blocks[4] = { 4, 8, 12, 16 };
  792. static const char chan_modes[4][16] = {
  793. "MONO", "DUAL_CHANNEL", "STEREO", "JOINT_STEREO"
  794. };
  795. static const char alloc_methods[2][12] = {
  796. "LOUDNESS", "SNR"
  797. };
  798. static const uint8_t subbands[2] = { 4, 8 };
  799. void print_sbc_header(struct sbc_frame_hdr *hdr)
  800. {
  801. RTKBT_DBG("syncword: %02x", hdr->syncword);
  802. RTKBT_DBG("freq %skHz", sample_freqs[hdr->sampling_frequency]);
  803. RTKBT_DBG("blocks %u", sbc_blocks[hdr->blocks]);
  804. RTKBT_DBG("channel mode %s", chan_modes[hdr->channel_mode]);
  805. RTKBT_DBG("allocation method %s",
  806. alloc_methods[hdr->allocation_method]);
  807. RTKBT_DBG("subbands %u", subbands[hdr->subbands]);
  808. }
  809. static void packets_count(uint16_t handle, uint16_t scid, uint16_t length,
  810. uint8_t direction, u8 *user_data)
  811. {
  812. rtk_prof_info *prof_info = NULL;
  813. rtk_conn_prof *hci_conn =
  814. find_connection_by_handle(&btrtl_coex, handle);
  815. if (NULL == hci_conn)
  816. return;
  817. if (0 == hci_conn->type) {
  818. if (!direction) //0: in
  819. prof_info =
  820. find_profile_by_handle_scid(&btrtl_coex, handle,
  821. scid);
  822. else //1: out
  823. prof_info =
  824. find_profile_by_handle_dcid(&btrtl_coex, handle,
  825. scid);
  826. if (!prof_info) {
  827. //RTKBT_DBG("packets_count: prof_info Not Find!");
  828. return;
  829. }
  830. /* avdtp media data */
  831. if (prof_info->profile_index == profile_a2dp &&
  832. prof_info->flags == A2DP_MEDIA) {
  833. if (!is_profile_busy(profile_a2dp)) {
  834. struct sbc_frame_hdr *sbc_header;
  835. struct rtp_header *rtph;
  836. u8 bitpool;
  837. update_profile_state(profile_a2dp, TRUE);
  838. if (!direction) {
  839. if (!(hci_conn->profile_bitmap & BIT(profile_sink))) {
  840. btrtl_coex.profile_bitmap |= BIT(profile_sink);
  841. hci_conn->profile_bitmap |= BIT(profile_sink);
  842. update_profile_connection(hci_conn, profile_sink, 1);
  843. }
  844. update_profile_state(profile_sink, TRUE);
  845. }
  846. /* We assume it is SBC if the packet length
  847. * is bigger than 100 bytes
  848. */
  849. if (length > 100) {
  850. RTKBT_INFO("Length %u", length);
  851. rtph = (struct rtp_header *)user_data;
  852. RTKBT_DBG("rtp: v %u, cc %u, pt %u",
  853. rtph->v, rtph->cc, rtph->pt);
  854. /* move forward */
  855. user_data += sizeof(struct rtp_header) +
  856. rtph->cc * 4 + 1;
  857. /* point to the sbc frame header */
  858. sbc_header = (struct sbc_frame_hdr *)user_data;
  859. bitpool = sbc_header->bitpool;
  860. print_sbc_header(sbc_header);
  861. RTKBT_DBG("bitpool %u", bitpool);
  862. rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_BITPOOL,
  863. 1, &bitpool);
  864. }
  865. }
  866. btrtl_coex.a2dp_packet_count++;
  867. }
  868. if (prof_info->profile_index == profile_pan)
  869. btrtl_coex.pan_packet_count++;
  870. }
  871. }
  872. #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
  873. static void count_a2dp_packet_timeout(struct timer_list *unused)
  874. #else
  875. static void count_a2dp_packet_timeout(unsigned long data)
  876. #endif
  877. {
  878. if (btrtl_coex.a2dp_packet_count)
  879. RTKBT_DBG("%s: a2dp_packet_count %d", __func__,
  880. btrtl_coex.a2dp_packet_count);
  881. if (btrtl_coex.a2dp_packet_count == 0) {
  882. if (is_profile_busy(profile_a2dp)) {
  883. RTKBT_DBG("%s: a2dp busy->idle!", __func__);
  884. update_profile_state(profile_a2dp, FALSE);
  885. if (btrtl_coex.profile_bitmap & BIT(profile_sink))
  886. update_profile_state(profile_sink, FALSE);
  887. }
  888. }
  889. btrtl_coex.a2dp_packet_count = 0;
  890. mod_timer(&btrtl_coex.a2dp_count_timer,
  891. jiffies + msecs_to_jiffies(1000));
  892. }
  893. #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
  894. static void count_pan_packet_timeout(struct timer_list *unused)
  895. #else
  896. static void count_pan_packet_timeout(unsigned long data)
  897. #endif
  898. {
  899. if (btrtl_coex.pan_packet_count)
  900. RTKBT_DBG("%s: pan_packet_count %d", __func__,
  901. btrtl_coex.pan_packet_count);
  902. if (btrtl_coex.pan_packet_count < PAN_PACKET_COUNT) {
  903. if (is_profile_busy(profile_pan)) {
  904. RTKBT_DBG("%s: pan busy->idle!", __func__);
  905. update_profile_state(profile_pan, FALSE);
  906. }
  907. } else {
  908. if (!is_profile_busy(profile_pan)) {
  909. RTKBT_DBG("timeout_handler: pan idle->busy!");
  910. update_profile_state(profile_pan, TRUE);
  911. }
  912. }
  913. btrtl_coex.pan_packet_count = 0;
  914. mod_timer(&btrtl_coex.pan_count_timer,
  915. jiffies + msecs_to_jiffies(1000));
  916. }
  917. #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
  918. static void count_hogp_packet_timeout(struct timer_list *unused)
  919. #else
  920. static void count_hogp_packet_timeout(unsigned long data)
  921. #endif
  922. {
  923. if (btrtl_coex.hogp_packet_count)
  924. RTKBT_DBG("%s: hogp_packet_count %d", __func__,
  925. btrtl_coex.hogp_packet_count);
  926. if (btrtl_coex.hogp_packet_count == 0) {
  927. if (is_profile_busy(profile_hogp)) {
  928. RTKBT_DBG("%s: hogp busy->idle!", __func__);
  929. update_profile_state(profile_hogp, FALSE);
  930. }
  931. }
  932. btrtl_coex.hogp_packet_count = 0;
  933. if (btrtl_coex.voice_packet_count)
  934. RTKBT_DBG("%s: voice_packet_count %d", __func__,
  935. btrtl_coex.voice_packet_count);
  936. if (btrtl_coex.voice_packet_count == 0) {
  937. if (is_profile_busy(profile_voice)) {
  938. RTKBT_DBG("%s: voice busy->idle!", __func__);
  939. update_profile_state(profile_voice, FALSE);
  940. }
  941. }
  942. btrtl_coex.voice_packet_count = 0;
  943. mod_timer(&btrtl_coex.hogp_count_timer,
  944. jiffies + msecs_to_jiffies(1000));
  945. }
  946. #ifdef RTB_SOFTWARE_MAILBOX
  947. #ifndef RTK_COEX_OVER_SYMBOL
  948. static int udpsocket_send(char *tx_msg, int msg_size)
  949. {
  950. u8 error = 0;
  951. struct msghdr udpmsg;
  952. mm_segment_t oldfs;
  953. struct iovec iov;
  954. RTKBT_DBG("send msg %s with len:%d", tx_msg, msg_size);
  955. if (btrtl_coex.sock_open) {
  956. iov.iov_base = (void *)tx_msg;
  957. iov.iov_len = msg_size;
  958. udpmsg.msg_name = &btrtl_coex.wifi_addr;
  959. udpmsg.msg_namelen = sizeof(struct sockaddr_in);
  960. #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
  961. udpmsg.msg_iov = &iov;
  962. udpmsg.msg_iovlen = 1;
  963. #else
  964. iov_iter_init(&udpmsg.msg_iter, WRITE, &iov, 1, msg_size);
  965. #endif
  966. udpmsg.msg_control = NULL;
  967. udpmsg.msg_controllen = 0;
  968. udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
  969. oldfs = get_fs();
  970. set_fs(KERNEL_DS);
  971. #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
  972. error = sock_sendmsg(btrtl_coex.udpsock, &udpmsg, msg_size);
  973. #else
  974. error = sock_sendmsg(btrtl_coex.udpsock, &udpmsg);
  975. #endif
  976. set_fs(oldfs);
  977. if (error < 0)
  978. RTKBT_DBG("Error when sendimg msg, error:%d", error);
  979. }
  980. return error;
  981. }
  982. #endif
  983. #ifdef RTK_COEX_OVER_SYMBOL
  984. /* Receive message from WiFi */
  985. u8 rtw_btcoex_wifi_to_bt(u8 *msg, u8 msg_size)
  986. {
  987. struct sk_buff *nskb;
  988. if (!rtw_coex_on) {
  989. RTKBT_WARN("Bluetooth is closed");
  990. return 0;
  991. }
  992. nskb = alloc_skb(msg_size, GFP_ATOMIC);
  993. if (!nskb) {
  994. RTKBT_ERR("Couldnt alloc skb for WiFi coex message");
  995. return 0;
  996. }
  997. memcpy(skb_put(nskb, msg_size), msg, msg_size);
  998. skb_queue_tail(&rtw_q, nskb);
  999. queue_work(rtw_wq, &rtw_work);
  1000. return 1;
  1001. }
  1002. EXPORT_SYMBOL(rtw_btcoex_wifi_to_bt);
  1003. static int rtk_send_coexmsg2wifi(u8 *msg, u8 size)
  1004. {
  1005. u8 result;
  1006. u8 (*btmsg_to_wifi)(u8 *, u8);
  1007. btmsg_to_wifi = __symbol_get(VMLINUX_SYMBOL_STR(rtw_btcoex_bt_to_wifi));
  1008. if (!btmsg_to_wifi) {
  1009. /* RTKBT_ERR("Couldnt get symbol"); */
  1010. return -1;
  1011. }
  1012. result = btmsg_to_wifi(msg, size);
  1013. __symbol_put(VMLINUX_SYMBOL_STR(rtw_btcoex_bt_to_wifi));
  1014. if (!result) {
  1015. RTKBT_ERR("Couldnt send coex msg to WiFi");
  1016. return -1;
  1017. } else if (result == 1){
  1018. /* successful to send message */
  1019. return 0;
  1020. } else {
  1021. RTKBT_ERR("Unknown result %d", result);
  1022. return -1;
  1023. }
  1024. }
  1025. static int rtkbt_process_coexskb(struct sk_buff *skb)
  1026. {
  1027. rtk_handle_event_from_wifi(skb->data);
  1028. return 0;
  1029. }
  1030. static void rtw_work_func(struct work_struct *work)
  1031. {
  1032. struct sk_buff *skb;
  1033. while ((skb = skb_dequeue(&rtw_q))) {
  1034. rtkbt_process_coexskb(skb);
  1035. kfree_skb(skb);
  1036. }
  1037. }
  1038. #endif
  1039. static int rtkbt_coexmsg_send(char *tx_msg, int msg_size)
  1040. {
  1041. #ifdef RTK_COEX_OVER_SYMBOL
  1042. return rtk_send_coexmsg2wifi((uint8_t *)tx_msg, (u8)msg_size);
  1043. #else
  1044. return udpsocket_send(tx_msg, msg_size);
  1045. #endif
  1046. }
  1047. #ifndef RTK_COEX_OVER_SYMBOL
  1048. static void udpsocket_recv_data(void)
  1049. {
  1050. u8 recv_data[512];
  1051. u32 len = 0;
  1052. u16 recv_length;
  1053. struct sk_buff *skb;
  1054. RTKBT_DBG("-");
  1055. spin_lock(&btrtl_coex.spin_lock_sock);
  1056. len = skb_queue_len(&btrtl_coex.sk->sk_receive_queue);
  1057. while (len > 0) {
  1058. skb = skb_dequeue(&btrtl_coex.sk->sk_receive_queue);
  1059. /*important: cut the udp header from skb->data! header length is 8 byte */
  1060. recv_length = skb->len - 8;
  1061. memset(recv_data, 0, sizeof(recv_data));
  1062. memcpy(recv_data, skb->data + 8, recv_length);
  1063. //RTKBT_DBG("received data: %s :with len %u", recv_data, recv_length);
  1064. rtk_handle_event_from_wifi(recv_data);
  1065. len--;
  1066. kfree_skb(skb);
  1067. }
  1068. spin_unlock(&btrtl_coex.spin_lock_sock);
  1069. }
  1070. #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
  1071. static void udpsocket_recv(struct sock *sk, int bytes)
  1072. #else
  1073. static void udpsocket_recv(struct sock *sk)
  1074. #endif
  1075. {
  1076. spin_lock(&btrtl_coex.spin_lock_sock);
  1077. btrtl_coex.sk = sk;
  1078. spin_unlock(&btrtl_coex.spin_lock_sock);
  1079. queue_delayed_work(btrtl_coex.sock_wq, &btrtl_coex.sock_work, 0);
  1080. }
  1081. static void create_udpsocket(void)
  1082. {
  1083. int err;
  1084. RTKBT_DBG("%s: connect_port: %d", __func__, CONNECT_PORT);
  1085. btrtl_coex.sock_open = 0;
  1086. err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
  1087. &btrtl_coex.udpsock);
  1088. if (err < 0) {
  1089. RTKBT_ERR("%s: sock create error, err = %d", __func__, err);
  1090. return;
  1091. }
  1092. memset(&btrtl_coex.addr, 0, sizeof(struct sockaddr_in));
  1093. btrtl_coex.addr.sin_family = AF_INET;
  1094. btrtl_coex.addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  1095. btrtl_coex.addr.sin_port = htons(CONNECT_PORT);
  1096. memset(&btrtl_coex.wifi_addr, 0, sizeof(struct sockaddr_in));
  1097. btrtl_coex.wifi_addr.sin_family = AF_INET;
  1098. btrtl_coex.wifi_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  1099. btrtl_coex.wifi_addr.sin_port = htons(CONNECT_PORT_WIFI);
  1100. err =
  1101. btrtl_coex.udpsock->ops->bind(btrtl_coex.udpsock,
  1102. (struct sockaddr *)&btrtl_coex.
  1103. addr, sizeof(struct sockaddr));
  1104. if (err < 0) {
  1105. sock_release(btrtl_coex.udpsock);
  1106. RTKBT_ERR("%s: sock bind error, err = %d",__func__, err);
  1107. return;
  1108. }
  1109. btrtl_coex.sock_open = 1;
  1110. btrtl_coex.udpsock->sk->sk_data_ready = udpsocket_recv;
  1111. }
  1112. #endif /* !RTK_COEX_OVER_SYMBOL */
  1113. static void rtk_notify_extension_version_to_wifi(void)
  1114. {
  1115. uint8_t para_length = 2;
  1116. char p_buf[2 + HCI_CMD_PREAMBLE_SIZE];
  1117. char *p = p_buf;
  1118. if (!btrtl_coex.wifi_on)
  1119. return;
  1120. UINT16_TO_STREAM(p, HCI_OP_HCI_EXTENSION_VERSION_NOTIFY);
  1121. *p++ = para_length;
  1122. UINT16_TO_STREAM(p, HCI_EXTENSION_VERSION);
  1123. RTKBT_DBG("extension version is 0x%x", HCI_EXTENSION_VERSION);
  1124. if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
  1125. RTKBT_ERR("%s: sock send error", __func__);
  1126. }
  1127. static void rtk_notify_btpatch_version_to_wifi(void)
  1128. {
  1129. uint8_t para_length = 4;
  1130. char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
  1131. char *p = p_buf;
  1132. if (!btrtl_coex.wifi_on)
  1133. return;
  1134. UINT16_TO_STREAM(p, HCI_OP_HCI_BT_PATCH_VER_NOTIFY);
  1135. *p++ = para_length;
  1136. UINT16_TO_STREAM(p, btrtl_coex.hci_reversion);
  1137. UINT16_TO_STREAM(p, btrtl_coex.lmp_subversion);
  1138. RTKBT_DBG("btpatch ver: len %u, hci_rev 0x%04x, lmp_subver 0x%04x",
  1139. para_length, btrtl_coex.hci_reversion,
  1140. btrtl_coex.lmp_subversion);
  1141. if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
  1142. RTKBT_ERR("%s: sock send error", __func__);
  1143. }
  1144. static void rtk_notify_afhmap_to_wifi(void)
  1145. {
  1146. uint8_t para_length = 13;
  1147. char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
  1148. char *p = p_buf;
  1149. uint8_t kk = 0;
  1150. if (!btrtl_coex.wifi_on)
  1151. return;
  1152. UINT16_TO_STREAM(p, HCI_OP_HCI_BT_AFH_MAP_NOTIFY);
  1153. *p++ = para_length;
  1154. *p++ = btrtl_coex.piconet_id;
  1155. *p++ = btrtl_coex.mode;
  1156. *p++ = 10;
  1157. memcpy(p, btrtl_coex.afh_map, 10);
  1158. RTKBT_DBG("afhmap, piconet_id is 0x%x, map type is 0x%x",
  1159. btrtl_coex.piconet_id, btrtl_coex.mode);
  1160. for (kk = 0; kk < 10; kk++)
  1161. RTKBT_DBG("afhmap data[%d] is 0x%x", kk,
  1162. btrtl_coex.afh_map[kk]);
  1163. if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
  1164. RTKBT_ERR("%s: sock send error", __func__);
  1165. }
  1166. static void rtk_notify_btcoex_to_wifi(uint8_t opcode, uint8_t status)
  1167. {
  1168. uint8_t para_length = 2;
  1169. char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
  1170. char *p = p_buf;
  1171. if (!btrtl_coex.wifi_on)
  1172. return;
  1173. UINT16_TO_STREAM(p, HCI_OP_HCI_BT_COEX_NOTIFY);
  1174. *p++ = para_length;
  1175. *p++ = opcode;
  1176. if (!status)
  1177. *p++ = 0;
  1178. else
  1179. *p++ = 1;
  1180. RTKBT_DBG("btcoex, opcode is 0x%x, status is 0x%x", opcode, status);
  1181. if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
  1182. RTKBT_ERR("%s: sock send error", __func__);
  1183. }
  1184. static void rtk_notify_btoperation_to_wifi(uint8_t operation,
  1185. uint8_t append_data_length,
  1186. uint8_t * append_data)
  1187. {
  1188. uint8_t para_length = 3 + append_data_length;
  1189. char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
  1190. char *p = p_buf;
  1191. uint8_t kk = 0;
  1192. if (!btrtl_coex.wifi_on)
  1193. return;
  1194. UINT16_TO_STREAM(p, HCI_OP_BT_OPERATION_NOTIFY);
  1195. *p++ = para_length;
  1196. *p++ = operation;
  1197. *p++ = append_data_length;
  1198. if (append_data_length)
  1199. memcpy(p, append_data, append_data_length);
  1200. RTKBT_DBG("btoperation: op 0x%02x, append_data_length %u",
  1201. operation, append_data_length);
  1202. if (append_data_length) {
  1203. for (kk = 0; kk < append_data_length; kk++)
  1204. RTKBT_DBG("append data is 0x%x", *(append_data + kk));
  1205. }
  1206. if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
  1207. RTKBT_ERR("%s: sock send error", __func__);
  1208. }
  1209. static void rtk_notify_info_to_wifi(uint8_t reason, uint8_t length,
  1210. uint8_t *report_info)
  1211. {
  1212. uint8_t para_length = 4 + length;
  1213. char buf[para_length + HCI_CMD_PREAMBLE_SIZE];
  1214. char *p = buf;
  1215. struct rtl_btinfo *report = (struct rtl_btinfo *)report_info;
  1216. if (length) {
  1217. RTKBT_DBG("bt info: cmd %2.2X", report->cmd);
  1218. RTKBT_DBG("bt info: len %2.2X", report->len);
  1219. RTKBT_DBG("bt info: data %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X",
  1220. report->data[0], report->data[1], report->data[2],
  1221. report->data[3], report->data[4], report->data[5]);
  1222. }
  1223. RTKBT_DBG("bt info: reason 0x%2x, length 0x%2x", reason, length);
  1224. if (!btrtl_coex.wifi_on)
  1225. return;
  1226. UINT16_TO_STREAM(p, HCI_OP_HCI_BT_INFO_NOTIFY);
  1227. *p++ = para_length;
  1228. *p++ = btrtl_coex.polling_enable;
  1229. *p++ = btrtl_coex.polling_interval;
  1230. *p++ = reason;
  1231. *p++ = length;
  1232. if (length)
  1233. memcpy(p, report_info, length);
  1234. RTKBT_DBG("para length %2x, polling_enable %u, poiiling_interval %u",
  1235. para_length, btrtl_coex.polling_enable,
  1236. btrtl_coex.polling_interval);
  1237. /* send BT INFO to Wi-Fi driver */
  1238. if (rtkbt_coexmsg_send(buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
  1239. RTKBT_ERR("%s: sock send error", __func__);
  1240. }
  1241. static void rtk_notify_regester_to_wifi(uint8_t * reg_value)
  1242. {
  1243. uint8_t para_length = 9;
  1244. char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
  1245. char *p = p_buf;
  1246. hci_mailbox_register *reg = (hci_mailbox_register *) reg_value;
  1247. if (!btrtl_coex.wifi_on)
  1248. return;
  1249. UINT16_TO_STREAM(p, HCI_OP_HCI_BT_REGISTER_VALUE_NOTIFY);
  1250. *p++ = para_length;
  1251. memcpy(p, reg_value, para_length);
  1252. RTKBT_DBG("bt register, register type is %x", reg->type);
  1253. RTKBT_DBG("bt register, register offset is %x", reg->offset);
  1254. RTKBT_DBG("bt register, register value is %x", reg->value);
  1255. if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
  1256. RTKBT_ERR("%s: sock send error", __func__);
  1257. }
  1258. #endif
  1259. void rtk_btcoex_parse_cmd(uint8_t *buffer, int count)
  1260. {
  1261. u16 opcode = (buffer[0]) + (buffer[1] << 8);
  1262. if (!test_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
  1263. RTKBT_INFO("%s: Coex is closed, ignore", __func__);
  1264. return;
  1265. }
  1266. switch (opcode) {
  1267. case HCI_OP_INQUIRY:
  1268. case HCI_OP_PERIODIC_INQ:
  1269. if (!btrtl_coex.isinquirying) {
  1270. btrtl_coex.isinquirying = 1;
  1271. #ifdef RTB_SOFTWARE_MAILBOX
  1272. RTKBT_DBG("hci (periodic)inq, notify wifi "
  1273. "inquiry start");
  1274. rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_START,
  1275. 0, NULL);
  1276. #else
  1277. RTKBT_INFO("hci (periodic)inq start");
  1278. #endif
  1279. }
  1280. break;
  1281. case HCI_OP_INQUIRY_CANCEL:
  1282. case HCI_OP_EXIT_PERIODIC_INQ:
  1283. if (btrtl_coex.isinquirying) {
  1284. btrtl_coex.isinquirying = 0;
  1285. #ifdef RTB_SOFTWARE_MAILBOX
  1286. RTKBT_DBG("hci (periodic)inq cancel/exit, notify wifi "
  1287. "inquiry stop");
  1288. rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0,
  1289. NULL);
  1290. #else
  1291. RTKBT_INFO("hci (periodic)inq cancel/exit");
  1292. #endif
  1293. }
  1294. break;
  1295. case HCI_OP_ACCEPT_CONN_REQ:
  1296. if (!btrtl_coex.ispaging) {
  1297. btrtl_coex.ispaging = 1;
  1298. #ifdef RTB_SOFTWARE_MAILBOX
  1299. RTKBT_DBG("hci accept connreq, notify wifi page start");
  1300. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_START, 0,
  1301. NULL);
  1302. #else
  1303. RTKBT_INFO("hci accept conn req");
  1304. #endif
  1305. }
  1306. break;
  1307. case HCI_OP_DISCONNECT:
  1308. RTKBT_INFO("HCI Disconnect, handle %04x, reason 0x%02x",
  1309. ((u16)buffer[4] << 8 | buffer[3]), buffer[5]);
  1310. break;
  1311. default:
  1312. break;
  1313. }
  1314. }
  1315. static void rtk_handle_inquiry_complete(void)
  1316. {
  1317. if (btrtl_coex.isinquirying) {
  1318. btrtl_coex.isinquirying = 0;
  1319. #ifdef RTB_SOFTWARE_MAILBOX
  1320. RTKBT_DBG("inq complete, notify wifi inquiry end");
  1321. rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0, NULL);
  1322. #else
  1323. RTKBT_INFO("inquiry complete");
  1324. #endif
  1325. }
  1326. }
  1327. static void rtk_handle_pin_code_req(void)
  1328. {
  1329. if (!btrtl_coex.ispairing) {
  1330. btrtl_coex.ispairing = 1;
  1331. #ifdef RTB_SOFTWARE_MAILBOX
  1332. RTKBT_DBG("pin code req, notify wifi pair start");
  1333. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_START, 0, NULL);
  1334. #else
  1335. RTKBT_INFO("pin code request");
  1336. #endif
  1337. }
  1338. }
  1339. static void rtk_handle_io_capa_req(void)
  1340. {
  1341. if (!btrtl_coex.ispairing) {
  1342. btrtl_coex.ispairing = 1;
  1343. #ifdef RTB_SOFTWARE_MAILBOX
  1344. RTKBT_DBG("io cap req, notify wifi pair start");
  1345. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_START, 0, NULL);
  1346. #else
  1347. RTKBT_INFO("io capability request");
  1348. #endif
  1349. }
  1350. }
  1351. static void rtk_handle_auth_request(void)
  1352. {
  1353. if (btrtl_coex.ispairing) {
  1354. btrtl_coex.ispairing = 0;
  1355. #ifdef RTB_SOFTWARE_MAILBOX
  1356. RTKBT_DBG("auth req, notify wifi pair end");
  1357. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
  1358. #else
  1359. RTKBT_INFO("authentication request");
  1360. #endif
  1361. }
  1362. }
  1363. static void rtk_handle_link_key_notify(void)
  1364. {
  1365. if (btrtl_coex.ispairing) {
  1366. btrtl_coex.ispairing = 0;
  1367. #ifdef RTB_SOFTWARE_MAILBOX
  1368. RTKBT_DBG("link key notify, notify wifi pair end");
  1369. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
  1370. #else
  1371. RTKBT_INFO("link key notify");
  1372. #endif
  1373. }
  1374. }
  1375. static void rtk_handle_mode_change_evt(u8 * p)
  1376. {
  1377. u16 mode_change_handle, mode_interval;
  1378. p++;
  1379. STREAM_TO_UINT16(mode_change_handle, p);
  1380. p++;
  1381. STREAM_TO_UINT16(mode_interval, p);
  1382. update_hid_active_state(mode_change_handle, mode_interval);
  1383. }
  1384. #ifdef RTB_SOFTWARE_MAILBOX
  1385. static void rtk_parse_vendor_mailbox_cmd_evt(u8 * p, u8 total_len)
  1386. {
  1387. u8 status, subcmd;
  1388. u8 temp_cmd[10];
  1389. status = *p++;
  1390. if (total_len <= 4) {
  1391. RTKBT_DBG("receive mailbox cmd from fw, total length <= 4");
  1392. return;
  1393. }
  1394. subcmd = *p++;
  1395. RTKBT_DBG("receive mailbox cmd from fw, subcmd is 0x%x, status is 0x%x",
  1396. subcmd, status);
  1397. switch (subcmd) {
  1398. case HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO:
  1399. if (status == 0) //success
  1400. rtk_notify_info_to_wifi(POLLING_RESPONSE,
  1401. RTL_BTINFO_LEN, (uint8_t *)p);
  1402. break;
  1403. case HCI_VENDOR_SUB_CMD_WIFI_CHANNEL_AND_BANDWIDTH_CMD:
  1404. rtk_notify_btcoex_to_wifi(WIFI_BW_CHNL_NOTIFY, status);
  1405. break;
  1406. case HCI_VENDOR_SUB_CMD_WIFI_FORCE_TX_POWER_CMD:
  1407. rtk_notify_btcoex_to_wifi(BT_POWER_DECREASE_CONTROL, status);
  1408. break;
  1409. case HCI_VENDOR_SUB_CMD_BT_ENABLE_IGNORE_WLAN_ACT_CMD:
  1410. rtk_notify_btcoex_to_wifi(IGNORE_WLAN_ACTIVE_CONTROL, status);
  1411. break;
  1412. case HCI_VENDOR_SUB_CMD_SET_BT_PSD_MODE:
  1413. rtk_notify_btcoex_to_wifi(BT_PSD_MODE_CONTROL, status);
  1414. break;
  1415. case HCI_VENDOR_SUB_CMD_SET_BT_LNA_CONSTRAINT:
  1416. rtk_notify_btcoex_to_wifi(LNA_CONSTRAIN_CONTROL, status);
  1417. break;
  1418. case HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_ENABLE:
  1419. break;
  1420. case HCI_VENDOR_SUB_CMD_BT_SET_TXRETRY_REPORT_PARAM:
  1421. break;
  1422. case HCI_VENDOR_SUB_CMD_BT_SET_PTATABLE:
  1423. break;
  1424. case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_L:
  1425. if (status == 0) {
  1426. memcpy(btrtl_coex.afh_map, p + 4, 4); /* cmd_idx, length, piconet_id, mode */
  1427. temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_M;
  1428. temp_cmd[1] = 2;
  1429. temp_cmd[2] = btrtl_coex.piconet_id;
  1430. temp_cmd[3] = btrtl_coex.mode;
  1431. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4,
  1432. temp_cmd);
  1433. } else {
  1434. memset(btrtl_coex.afh_map, 0, 10);
  1435. rtk_notify_afhmap_to_wifi();
  1436. }
  1437. break;
  1438. case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_M:
  1439. if (status == 0) {
  1440. memcpy(btrtl_coex.afh_map + 4, p + 4, 4);
  1441. temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_H;
  1442. temp_cmd[1] = 2;
  1443. temp_cmd[2] = btrtl_coex.piconet_id;
  1444. temp_cmd[3] = btrtl_coex.mode;
  1445. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4,
  1446. temp_cmd);
  1447. } else {
  1448. memset(btrtl_coex.afh_map, 0, 10);
  1449. rtk_notify_afhmap_to_wifi();
  1450. }
  1451. break;
  1452. case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_H:
  1453. if (status == 0)
  1454. memcpy(btrtl_coex.afh_map + 8, p + 4, 2);
  1455. else
  1456. memset(btrtl_coex.afh_map, 0, 10);
  1457. rtk_notify_afhmap_to_wifi();
  1458. break;
  1459. case HCI_VENDOR_SUB_CMD_RD_REG_REQ:
  1460. if (status == 0)
  1461. rtk_notify_regester_to_wifi(p + 3); /* cmd_idx,length,regist type */
  1462. break;
  1463. case HCI_VENDOR_SUB_CMD_WR_REG_REQ:
  1464. rtk_notify_btcoex_to_wifi(BT_REGISTER_ACCESS, status);
  1465. break;
  1466. default:
  1467. break;
  1468. }
  1469. }
  1470. #endif /* RTB_SOFTWARE_MAILBOX */
  1471. static void rtk_handle_cmd_complete_evt(u8 total_len, u8 * p)
  1472. {
  1473. u16 opcode;
  1474. p++;
  1475. STREAM_TO_UINT16(opcode, p);
  1476. //RTKBT_DBG("cmd_complete, opcode is 0x%x", opcode);
  1477. if (opcode == HCI_OP_PERIODIC_INQ) {
  1478. if (*p++ && btrtl_coex.isinquirying) {
  1479. btrtl_coex.isinquirying = 0;
  1480. #ifdef RTB_SOFTWARE_MAILBOX
  1481. RTKBT_DBG("hci period inq, start error, notify wifi "
  1482. "inquiry stop");
  1483. rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0,
  1484. NULL);
  1485. #else
  1486. RTKBT_INFO("hci period inquiry start error");
  1487. #endif
  1488. }
  1489. }
  1490. if (opcode == HCI_OP_READ_LOCAL_VERSION) {
  1491. if (!(*p++)) {
  1492. p++;
  1493. STREAM_TO_UINT16(btrtl_coex.hci_reversion, p);
  1494. p += 3;
  1495. STREAM_TO_UINT16(btrtl_coex.lmp_subversion, p);
  1496. RTKBT_DBG("BTCOEX hci_rev 0x%04x",
  1497. btrtl_coex.hci_reversion);
  1498. RTKBT_DBG("BTCOEX lmp_subver 0x%04x",
  1499. btrtl_coex.lmp_subversion);
  1500. }
  1501. }
  1502. #ifdef RTB_SOFTWARE_MAILBOX
  1503. if (opcode == HCI_VENDOR_MAILBOX_CMD) {
  1504. rtk_parse_vendor_mailbox_cmd_evt(p, total_len);
  1505. }
  1506. #endif
  1507. }
  1508. static void rtk_handle_cmd_status_evt(u8 * p)
  1509. {
  1510. u16 opcode;
  1511. u8 status;
  1512. status = *p++;
  1513. p++;
  1514. STREAM_TO_UINT16(opcode, p);
  1515. //RTKBT_DBG("cmd_status, opcode is 0x%x", opcode);
  1516. if ((opcode == HCI_OP_INQUIRY) && (status)) {
  1517. if (btrtl_coex.isinquirying) {
  1518. btrtl_coex.isinquirying = 0;
  1519. #ifdef RTB_SOFTWARE_MAILBOX
  1520. RTKBT_DBG("hci inq, start error, notify wifi inq stop");
  1521. rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0,
  1522. NULL);
  1523. #else
  1524. RTKBT_INFO("hci inquiry start error");
  1525. #endif
  1526. }
  1527. }
  1528. if (opcode == HCI_OP_CREATE_CONN) {
  1529. if (!status && !btrtl_coex.ispaging) {
  1530. btrtl_coex.ispaging = 1;
  1531. #ifdef RTB_SOFTWARE_MAILBOX
  1532. RTKBT_DBG("hci create conn, notify wifi start page");
  1533. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_START, 0,
  1534. NULL);
  1535. #else
  1536. RTKBT_INFO("hci create connection, start paging");
  1537. #endif
  1538. }
  1539. }
  1540. }
  1541. static void rtk_handle_connection_complete_evt(u8 * p)
  1542. {
  1543. u16 handle;
  1544. u8 status, link_type;
  1545. rtk_conn_prof *hci_conn = NULL;
  1546. status = *p++;
  1547. STREAM_TO_UINT16(handle, p);
  1548. p += 6;
  1549. link_type = *p++;
  1550. RTKBT_INFO("connected, handle %04x, status 0x%02x", handle, status);
  1551. if (status == 0) {
  1552. if (btrtl_coex.ispaging) {
  1553. btrtl_coex.ispaging = 0;
  1554. #ifdef RTB_SOFTWARE_MAILBOX
  1555. RTKBT_DBG("notify wifi page success end");
  1556. rtk_notify_btoperation_to_wifi
  1557. (BT_OPCODE_PAGE_SUCCESS_END, 0, NULL);
  1558. #else
  1559. RTKBT_INFO("Page success");
  1560. #endif
  1561. }
  1562. hci_conn = find_connection_by_handle(&btrtl_coex, handle);
  1563. if (hci_conn == NULL) {
  1564. hci_conn = allocate_connection_by_handle(handle);
  1565. if (hci_conn) {
  1566. add_connection_to_hash(&btrtl_coex,
  1567. hci_conn);
  1568. hci_conn->profile_bitmap = 0;
  1569. memset(hci_conn->profile_refcount, 0, 8);
  1570. if ((0 == link_type) || (2 == link_type)) { //sco or esco
  1571. hci_conn->type = 1;
  1572. update_profile_connection(hci_conn,
  1573. profile_sco,
  1574. TRUE);
  1575. } else
  1576. hci_conn->type = 0;
  1577. } else {
  1578. RTKBT_ERR("hci connection allocate fail");
  1579. }
  1580. } else {
  1581. RTKBT_DBG("hci conn handle 0x%04x already existed!",
  1582. handle);
  1583. hci_conn->profile_bitmap = 0;
  1584. memset(hci_conn->profile_refcount, 0, 8);
  1585. if ((0 == link_type) || (2 == link_type)) { //sco or esco
  1586. hci_conn->type = 1;
  1587. update_profile_connection(hci_conn, profile_sco,
  1588. TRUE);
  1589. } else
  1590. hci_conn->type = 0;
  1591. }
  1592. } else if (btrtl_coex.ispaging) {
  1593. btrtl_coex.ispaging = 0;
  1594. #ifdef RTB_SOFTWARE_MAILBOX
  1595. RTKBT_DBG("notify wifi page unsuccess end");
  1596. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_UNSUCCESS_END, 0,
  1597. NULL);
  1598. #else
  1599. RTKBT_INFO("Page failed");
  1600. #endif
  1601. }
  1602. }
  1603. static void rtk_handle_le_connection_complete_evt(u8 enhanced, u8 * p)
  1604. {
  1605. u16 handle, interval;
  1606. u8 status;
  1607. rtk_conn_prof *hci_conn = NULL;
  1608. status = *p++;
  1609. STREAM_TO_UINT16(handle, p);
  1610. if (!enhanced)
  1611. p += 8; /* role, address type, address */
  1612. else
  1613. p += (8 + 12); /* plus two bluetooth addresses */
  1614. STREAM_TO_UINT16(interval, p);
  1615. RTKBT_INFO("LE connected, handle %04x, status 0x%02x, interval %u",
  1616. handle, status, interval);
  1617. if (status == 0) {
  1618. if (btrtl_coex.ispaging) {
  1619. btrtl_coex.ispaging = 0;
  1620. #ifdef RTB_SOFTWARE_MAILBOX
  1621. RTKBT_DBG("notify wifi page success end");
  1622. rtk_notify_btoperation_to_wifi
  1623. (BT_OPCODE_PAGE_SUCCESS_END, 0, NULL);
  1624. #else
  1625. RTKBT_INFO("Page success end");
  1626. #endif
  1627. }
  1628. hci_conn = find_connection_by_handle(&btrtl_coex, handle);
  1629. if (hci_conn == NULL) {
  1630. hci_conn = allocate_connection_by_handle(handle);
  1631. if (hci_conn) {
  1632. add_connection_to_hash(&btrtl_coex,
  1633. hci_conn);
  1634. hci_conn->profile_bitmap = 0;
  1635. memset(hci_conn->profile_refcount, 0, 8);
  1636. hci_conn->type = 2;
  1637. update_profile_connection(hci_conn, profile_hid, TRUE); //for coex, le is the same as hid
  1638. update_hid_active_state(handle, interval);
  1639. } else {
  1640. RTKBT_ERR("hci connection allocate fail");
  1641. }
  1642. } else {
  1643. RTKBT_DBG("hci conn handle 0x%04x already existed!",
  1644. handle);
  1645. hci_conn->profile_bitmap = 0;
  1646. memset(hci_conn->profile_refcount, 0, 8);
  1647. hci_conn->type = 2;
  1648. update_profile_connection(hci_conn, profile_hid, TRUE);
  1649. update_hid_active_state(handle, interval);
  1650. }
  1651. } else if (btrtl_coex.ispaging) {
  1652. btrtl_coex.ispaging = 0;
  1653. #ifdef RTB_SOFTWARE_MAILBOX
  1654. RTKBT_DBG("notify wifi page unsuccess end");
  1655. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_UNSUCCESS_END, 0,
  1656. NULL);
  1657. #else
  1658. RTKBT_INFO("Page failed");
  1659. #endif
  1660. }
  1661. }
  1662. static void rtk_handle_le_connection_update_complete_evt(u8 * p)
  1663. {
  1664. u16 handle, interval;
  1665. /* u8 status; */
  1666. /* status = *p++; */
  1667. p++;
  1668. STREAM_TO_UINT16(handle, p);
  1669. STREAM_TO_UINT16(interval, p);
  1670. update_hid_active_state(handle, interval);
  1671. }
  1672. static void rtk_handle_le_meta_evt(u8 * p)
  1673. {
  1674. u8 sub_event = *p++;
  1675. switch (sub_event) {
  1676. case HCI_EV_LE_CONN_COMPLETE:
  1677. rtk_handle_le_connection_complete_evt(0, p);
  1678. break;
  1679. case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
  1680. rtk_handle_le_connection_complete_evt(1, p);
  1681. break;
  1682. case HCI_EV_LE_CONN_UPDATE_COMPLETE:
  1683. rtk_handle_le_connection_update_complete_evt(p);
  1684. break;
  1685. default:
  1686. break;
  1687. }
  1688. }
  1689. static u8 disconn_profile(struct rtl_hci_conn *conn, u8 pfe_index)
  1690. {
  1691. u8 need_update = 0;
  1692. if (!btrtl_coex.profile_refcount[pfe_index]) {
  1693. RTKBT_WARN("profile %u ref is 0", pfe_index);
  1694. return 0;
  1695. }
  1696. btrtl_coex.profile_refcount[pfe_index]--;
  1697. RTKBT_INFO("%s: profile_ref[%u] %u", __func__, pfe_index,
  1698. btrtl_coex.profile_refcount[pfe_index]);
  1699. if (!btrtl_coex.profile_refcount[pfe_index]) {
  1700. need_update = 1;
  1701. btrtl_coex.profile_bitmap &= ~(BIT(pfe_index));
  1702. /* if profile does not exist, status is meaningless */
  1703. btrtl_coex.profile_status &= ~(BIT(pfe_index));
  1704. rtk_check_del_timer(pfe_index);
  1705. }
  1706. if (conn->profile_refcount[pfe_index])
  1707. conn->profile_refcount[pfe_index]--;
  1708. else
  1709. RTKBT_INFO("%s: conn pfe ref[%u] is 0", __func__,
  1710. conn->profile_refcount[pfe_index]);
  1711. if (!conn->profile_refcount[pfe_index]) {
  1712. need_update = 1;
  1713. conn->profile_bitmap &= ~(BIT(pfe_index));
  1714. /* clear profile_hid_interval if need */
  1715. if ((profile_hid == pfe_index) &&
  1716. (conn->profile_bitmap & (BIT(profile_hid_interval)))) {
  1717. conn->profile_bitmap &= ~(BIT(profile_hid_interval));
  1718. if (btrtl_coex.profile_refcount[profile_hid_interval])
  1719. btrtl_coex.profile_refcount[profile_hid_interval]--;
  1720. }
  1721. }
  1722. return need_update;
  1723. }
  1724. static void disconn_acl(u16 handle, struct rtl_hci_conn *conn)
  1725. {
  1726. struct rtl_coex_struct *coex = &btrtl_coex;
  1727. rtk_prof_info *prof_info = NULL;
  1728. struct list_head *iter = NULL, *temp = NULL;
  1729. u8 need_update = 0;
  1730. spin_lock(&coex->spin_lock_profile);
  1731. list_for_each_safe(iter, temp, &coex->profile_list) {
  1732. prof_info = list_entry(iter, rtk_prof_info, list);
  1733. if (handle == prof_info->handle) {
  1734. RTKBT_DBG("hci disconn, hndl %x, psm %x, dcid %x, "
  1735. "scid %x, profile %u", prof_info->handle,
  1736. prof_info->psm, prof_info->dcid,
  1737. prof_info->scid, prof_info->profile_index);
  1738. //If both scid and dcid > 0, L2cap connection is exist.
  1739. need_update |= disconn_profile(conn,
  1740. prof_info->profile_index);
  1741. if ((prof_info->flags & A2DP_MEDIA) &&
  1742. (conn->profile_bitmap & BIT(profile_sink)))
  1743. need_update |= disconn_profile(conn,
  1744. profile_sink);
  1745. delete_profile_from_hash(prof_info);
  1746. }
  1747. }
  1748. if (need_update)
  1749. rtk_notify_profileinfo_to_fw();
  1750. spin_unlock(&coex->spin_lock_profile);
  1751. }
  1752. static void rtk_handle_disconnect_complete_evt(u8 * p)
  1753. {
  1754. u16 handle;
  1755. u8 status;
  1756. u8 reason;
  1757. rtk_conn_prof *hci_conn = NULL;
  1758. if (btrtl_coex.ispairing) { //for slave: connection will be disconnected if authentication fail
  1759. btrtl_coex.ispairing = 0;
  1760. #ifdef RTB_SOFTWARE_MAILBOX
  1761. RTKBT_DBG("hci disc complete, notify wifi pair end");
  1762. rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
  1763. #else
  1764. RTKBT_INFO("hci disconnection complete");
  1765. #endif
  1766. }
  1767. status = *p++;
  1768. STREAM_TO_UINT16(handle, p);
  1769. reason = *p;
  1770. RTKBT_INFO("disconn cmpl evt: status 0x%02x, handle %04x, reason 0x%02x",
  1771. status, handle, reason);
  1772. if (status == 0) {
  1773. RTKBT_DBG("process disconn complete event.");
  1774. hci_conn = find_connection_by_handle(&btrtl_coex, handle);
  1775. if (hci_conn) {
  1776. switch (hci_conn->type) {
  1777. case 0:
  1778. /* FIXME: If this is interrupted by l2cap rx,
  1779. * there may be deadlock on spin_lock_profile */
  1780. disconn_acl(handle, hci_conn);
  1781. break;
  1782. case 1:
  1783. update_profile_connection(hci_conn, profile_sco,
  1784. FALSE);
  1785. break;
  1786. case 2:
  1787. update_profile_connection(hci_conn, profile_hid,
  1788. FALSE);
  1789. break;
  1790. default:
  1791. break;
  1792. }
  1793. delete_connection_from_hash(hci_conn);
  1794. } else
  1795. RTKBT_ERR("hci conn handle 0x%04x not found", handle);
  1796. }
  1797. }
  1798. static void rtk_handle_specific_evt(u8 * p)
  1799. {
  1800. u16 subcode;
  1801. STREAM_TO_UINT16(subcode, p);
  1802. if (subcode == HCI_VENDOR_PTA_AUTO_REPORT_EVENT) {
  1803. #ifdef RTB_SOFTWARE_MAILBOX
  1804. RTKBT_DBG("notify wifi driver with autoreport data");
  1805. rtk_notify_info_to_wifi(AUTO_REPORT, RTL_BTINFO_LEN,
  1806. (uint8_t *)p);
  1807. #else
  1808. RTKBT_INFO("auto report data");
  1809. #endif
  1810. }
  1811. }
  1812. static void rtk_parse_event_data(struct rtl_coex_struct *coex,
  1813. u8 *data, u16 len)
  1814. {
  1815. u8 *p = data;
  1816. u8 event_code = *p++;
  1817. u8 total_len = *p++;
  1818. (void)coex;
  1819. (void)&len;
  1820. switch (event_code) {
  1821. case HCI_EV_INQUIRY_COMPLETE:
  1822. rtk_handle_inquiry_complete();
  1823. break;
  1824. case HCI_EV_PIN_CODE_REQ:
  1825. rtk_handle_pin_code_req();
  1826. break;
  1827. case HCI_EV_IO_CAPA_REQUEST:
  1828. rtk_handle_io_capa_req();
  1829. break;
  1830. case HCI_EV_AUTH_COMPLETE:
  1831. rtk_handle_auth_request();
  1832. break;
  1833. case HCI_EV_LINK_KEY_NOTIFY:
  1834. rtk_handle_link_key_notify();
  1835. break;
  1836. case HCI_EV_MODE_CHANGE:
  1837. rtk_handle_mode_change_evt(p);
  1838. break;
  1839. case HCI_EV_CMD_COMPLETE:
  1840. rtk_handle_cmd_complete_evt(total_len, p);
  1841. break;
  1842. case HCI_EV_CMD_STATUS:
  1843. rtk_handle_cmd_status_evt(p);
  1844. break;
  1845. case HCI_EV_CONN_COMPLETE:
  1846. case HCI_EV_SYNC_CONN_COMPLETE:
  1847. rtk_handle_connection_complete_evt(p);
  1848. break;
  1849. case HCI_EV_DISCONN_COMPLETE:
  1850. rtk_handle_disconnect_complete_evt(p);
  1851. break;
  1852. case HCI_EV_LE_META:
  1853. rtk_handle_le_meta_evt(p);
  1854. break;
  1855. case HCI_EV_VENDOR_SPECIFIC:
  1856. rtk_handle_specific_evt(p);
  1857. break;
  1858. default:
  1859. break;
  1860. }
  1861. }
  1862. const char l2_dir_str[][4] = {
  1863. "RX", "TX",
  1864. };
  1865. void rtl_process_l2_sig(struct rtl_l2_buff *l2)
  1866. {
  1867. /* u8 flag; */
  1868. u8 code;
  1869. /* u8 identifier; */
  1870. u16 handle;
  1871. /* u16 total_len; */
  1872. /* u16 pdu_len, channel_id; */
  1873. /* u16 command_len; */
  1874. u16 psm, scid, dcid, result;
  1875. /* u16 status; */
  1876. u8 *pp = l2->data;
  1877. STREAM_TO_UINT16(handle, pp);
  1878. /* flag = handle >> 12; */
  1879. handle = handle & 0x0FFF;
  1880. /* STREAM_TO_UINT16(total_len, pp); */
  1881. pp += 2; /* data total length */
  1882. /* STREAM_TO_UINT16(pdu_len, pp);
  1883. * STREAM_TO_UINT16(channel_id, pp); */
  1884. pp += 4; /* l2 len and channel id */
  1885. code = *pp++;
  1886. switch (code) {
  1887. case L2CAP_CONN_REQ:
  1888. /* identifier = *pp++; */
  1889. pp++;
  1890. /* STREAM_TO_UINT16(command_len, pp); */
  1891. pp += 2;
  1892. STREAM_TO_UINT16(psm, pp);
  1893. STREAM_TO_UINT16(scid, pp);
  1894. RTKBT_DBG("%s l2cap conn req, hndl 0x%04x, PSM 0x%04x, "
  1895. "scid 0x%04x", l2_dir_str[l2->out], handle, psm,
  1896. scid);
  1897. handle_l2cap_con_req(handle, psm, scid, l2->out);
  1898. break;
  1899. case L2CAP_CONN_RSP:
  1900. /* identifier = *pp++; */
  1901. pp++;
  1902. /* STREAM_TO_UINT16(command_len, pp); */
  1903. pp += 2;
  1904. STREAM_TO_UINT16(dcid, pp);
  1905. STREAM_TO_UINT16(scid, pp);
  1906. STREAM_TO_UINT16(result, pp);
  1907. /* STREAM_TO_UINT16(status, pp); */
  1908. pp += 2;
  1909. RTKBT_DBG("%s l2cap conn rsp, hndl 0x%04x, dcid 0x%04x, "
  1910. "scid 0x%04x, result 0x%04x", l2_dir_str[l2->out],
  1911. handle, dcid, scid, result);
  1912. handle_l2cap_con_rsp(handle, dcid, scid, l2->out, result);
  1913. break;
  1914. case L2CAP_DISCONN_REQ:
  1915. /* identifier = *pp++; */
  1916. pp++;
  1917. /* STREAM_TO_UINT16(command_len, pp); */
  1918. pp += 2;
  1919. STREAM_TO_UINT16(dcid, pp);
  1920. STREAM_TO_UINT16(scid, pp);
  1921. RTKBT_DBG("%s l2cap disconn req, hndl 0x%04x, dcid 0x%04x, "
  1922. "scid 0x%04x", l2_dir_str[l2->out], handle, dcid, scid);
  1923. handle_l2cap_discon_req(handle, dcid, scid, l2->out);
  1924. break;
  1925. default:
  1926. RTKBT_DBG("undesired l2 command %u", code);
  1927. break;
  1928. }
  1929. }
  1930. static void rtl_l2_data_process(u8 *pp, u16 len, int dir)
  1931. {
  1932. u8 code;
  1933. u8 flag;
  1934. u16 handle, pdu_len, channel_id;
  1935. /* u16 total_len; */
  1936. struct rtl_l2_buff *l2 = NULL;
  1937. u8 *hd = pp;
  1938. /* RTKBT_DBG("l2 sig data %p, len %u, dir %d", pp, len, dir); */
  1939. STREAM_TO_UINT16(handle, pp);
  1940. flag = handle >> 12;
  1941. handle = handle & 0x0FFF;
  1942. /* STREAM_TO_UINT16(total_len, pp); */
  1943. pp += 2; /* data total length */
  1944. STREAM_TO_UINT16(pdu_len, pp);
  1945. STREAM_TO_UINT16(channel_id, pp);
  1946. if (channel_id == 0x0001) {
  1947. code = *pp++;
  1948. switch (code) {
  1949. case L2CAP_CONN_REQ:
  1950. case L2CAP_CONN_RSP:
  1951. case L2CAP_DISCONN_REQ:
  1952. RTKBT_DBG("l2cap op %u, len %u, out %d", code, len,
  1953. dir);
  1954. l2 = rtl_l2_node_get(&btrtl_coex);
  1955. if (l2) {
  1956. u16 n;
  1957. n = min_t(uint, len, L2_MAX_SUBSEC_LEN);
  1958. memcpy(l2->data, hd, n);
  1959. l2->out = dir;
  1960. rtl_l2_node_to_used(&btrtl_coex, l2);
  1961. queue_delayed_work(btrtl_coex.fw_wq,
  1962. &btrtl_coex.l2_work, 0);
  1963. } else
  1964. RTKBT_ERR("%s: failed to get l2 node",
  1965. __func__);
  1966. break;
  1967. case L2CAP_DISCONN_RSP:
  1968. break;
  1969. default:
  1970. break;
  1971. }
  1972. } else {
  1973. if ((flag != 0x01) && (is_profile_connected(profile_a2dp) ||
  1974. is_profile_connected(profile_pan)))
  1975. /* Do not count the continuous packets */
  1976. packets_count(handle, channel_id, pdu_len, dir, pp);
  1977. }
  1978. return;
  1979. }
  1980. static void rtl_l2_work(struct work_struct *work)
  1981. {
  1982. struct rtl_coex_struct *coex;
  1983. struct rtl_l2_buff *l2;
  1984. unsigned long flags;
  1985. coex = container_of(work, struct rtl_coex_struct, l2_work.work);
  1986. spin_lock_irqsave(&coex->buff_lock, flags);
  1987. while (!list_empty(&coex->l2_used_list)) {
  1988. l2 = list_entry(coex->l2_used_list.next, struct rtl_l2_buff,
  1989. list);
  1990. list_del(&l2->list);
  1991. spin_unlock_irqrestore(&coex->buff_lock, flags);
  1992. rtl_process_l2_sig(l2);
  1993. spin_lock_irqsave(&coex->buff_lock, flags);
  1994. list_add_tail(&l2->list, &coex->l2_free_list);
  1995. }
  1996. spin_unlock_irqrestore(&coex->buff_lock, flags);
  1997. return;
  1998. }
  1999. static void rtl_ev_work(struct work_struct *work)
  2000. {
  2001. struct rtl_coex_struct *coex;
  2002. struct rtl_hci_ev *ev;
  2003. unsigned long flags;
  2004. coex = container_of(work, struct rtl_coex_struct, fw_work.work);
  2005. spin_lock_irqsave(&coex->buff_lock, flags);
  2006. while (!list_empty(&coex->ev_used_list)) {
  2007. ev = list_entry(coex->ev_used_list.next, struct rtl_hci_ev,
  2008. list);
  2009. list_del(&ev->list);
  2010. spin_unlock_irqrestore(&coex->buff_lock, flags);
  2011. rtk_parse_event_data(coex, ev->data, ev->len);
  2012. spin_lock_irqsave(&coex->buff_lock, flags);
  2013. list_add_tail(&ev->list, &coex->ev_free_list);
  2014. }
  2015. spin_unlock_irqrestore(&coex->buff_lock, flags);
  2016. }
  2017. static inline int cmd_cmplt_filter_out(u8 *buf)
  2018. {
  2019. u16 opcode;
  2020. opcode = buf[3] | (buf[4] << 8);
  2021. switch (opcode) {
  2022. case HCI_OP_PERIODIC_INQ:
  2023. case HCI_OP_READ_LOCAL_VERSION:
  2024. #ifdef RTB_SOFTWARE_MAILBOX
  2025. case HCI_VENDOR_MAILBOX_CMD:
  2026. #endif
  2027. return 0;
  2028. default:
  2029. return 1;
  2030. }
  2031. }
  2032. static inline int cmd_status_filter_out(u8 *buf)
  2033. {
  2034. u16 opcode;
  2035. opcode = buf[4] | (buf[5] << 8);
  2036. switch (opcode) {
  2037. case HCI_OP_INQUIRY:
  2038. case HCI_OP_CREATE_CONN:
  2039. return 0;
  2040. default:
  2041. return 1;
  2042. }
  2043. }
  2044. int ev_filter_out(u8 *buf)
  2045. {
  2046. switch (buf[0]) {
  2047. case HCI_EV_INQUIRY_COMPLETE:
  2048. case HCI_EV_PIN_CODE_REQ:
  2049. case HCI_EV_IO_CAPA_REQUEST:
  2050. case HCI_EV_AUTH_COMPLETE:
  2051. case HCI_EV_LINK_KEY_NOTIFY:
  2052. case HCI_EV_MODE_CHANGE:
  2053. case HCI_EV_CONN_COMPLETE:
  2054. case HCI_EV_SYNC_CONN_COMPLETE:
  2055. case HCI_EV_DISCONN_COMPLETE:
  2056. case HCI_EV_VENDOR_SPECIFIC:
  2057. return 0;
  2058. case HCI_EV_LE_META:
  2059. /* Ignore frequent but not useful events that result in
  2060. * costing too much space.
  2061. */
  2062. switch (buf[2]) {
  2063. case HCI_EV_LE_CONN_COMPLETE:
  2064. case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
  2065. case HCI_EV_LE_CONN_UPDATE_COMPLETE:
  2066. return 0;
  2067. }
  2068. return 1;
  2069. case HCI_EV_CMD_COMPLETE:
  2070. return cmd_cmplt_filter_out(buf);
  2071. case HCI_EV_CMD_STATUS:
  2072. return cmd_status_filter_out(buf);
  2073. default:
  2074. return 1;
  2075. }
  2076. }
  2077. static void rtk_btcoex_evt_enqueue(__u8 *s, __u16 count)
  2078. {
  2079. struct rtl_hci_ev *ev;
  2080. if (ev_filter_out(s))
  2081. return;
  2082. ev = rtl_ev_node_get(&btrtl_coex);
  2083. if (!ev) {
  2084. RTKBT_ERR("%s: no free ev node.", __func__);
  2085. return;
  2086. }
  2087. if (count > MAX_LEN_OF_HCI_EV) {
  2088. memcpy(ev->data, s, MAX_LEN_OF_HCI_EV);
  2089. ev->len = MAX_LEN_OF_HCI_EV;
  2090. } else {
  2091. memcpy(ev->data, s, count);
  2092. ev->len = count;
  2093. }
  2094. rtl_ev_node_to_used(&btrtl_coex, ev);
  2095. queue_delayed_work(btrtl_coex.fw_wq, &btrtl_coex.fw_work, 0);
  2096. }
  2097. /* Context: in_interrupt() */
  2098. void rtk_btcoex_parse_event(uint8_t *buffer, int count)
  2099. {
  2100. struct rtl_coex_struct *coex = &btrtl_coex;
  2101. __u8 *tbuff;
  2102. __u16 elen = 0;
  2103. /* RTKBT_DBG("%s: parse ev.", __func__); */
  2104. if (!test_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
  2105. /* RTKBT_INFO("%s: Coex is closed, ignore", __func__); */
  2106. RTKBT_INFO("%s: Coex is closed, ignore %x, %x",
  2107. __func__, buffer[0], buffer[1]);
  2108. return;
  2109. }
  2110. spin_lock(&coex->rxlock);
  2111. /* coex->tbuff will be set to NULL when initializing or
  2112. * there is a complete frame or there is start of a frame */
  2113. tbuff = coex->tbuff;
  2114. while (count) {
  2115. int len;
  2116. /* Start of a frame */
  2117. if (!tbuff) {
  2118. tbuff = coex->back_buff;
  2119. coex->tbuff = NULL;
  2120. coex->elen = 0;
  2121. coex->pkt_type = HCI_EVENT_PKT;
  2122. coex->expect = HCI_EVENT_HDR_SIZE;
  2123. }
  2124. len = min_t(uint, coex->expect, count);
  2125. memcpy(tbuff, buffer, len);
  2126. tbuff += len;
  2127. coex->elen += len;
  2128. count -= len;
  2129. buffer += len;
  2130. coex->expect -= len;
  2131. if (coex->elen == HCI_EVENT_HDR_SIZE) {
  2132. /* Complete event header */
  2133. coex->expect =
  2134. ((struct hci_event_hdr *)coex->back_buff)->plen;
  2135. if (coex->expect > HCI_MAX_EVENT_SIZE - coex->elen) {
  2136. tbuff = NULL;
  2137. coex->elen = 0;
  2138. RTKBT_ERR("tbuff room is not enough");
  2139. break;
  2140. }
  2141. }
  2142. if (coex->expect == 0) {
  2143. /* Complete frame */
  2144. elen = coex->elen;
  2145. spin_unlock(&coex->rxlock);
  2146. rtk_btcoex_evt_enqueue(coex->back_buff, elen);
  2147. spin_lock(&coex->rxlock);
  2148. tbuff = NULL;
  2149. coex->elen = 0;
  2150. }
  2151. }
  2152. /* coex->tbuff would be non-NULL if there isn't a complete frame
  2153. * And it will be updated next time */
  2154. coex->tbuff = tbuff;
  2155. spin_unlock(&coex->rxlock);
  2156. }
  2157. void rtk_btcoex_parse_l2cap_data_tx(uint8_t *buffer, int count)
  2158. {
  2159. if (!test_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
  2160. RTKBT_INFO("%s: Coex is closed, ignore", __func__);
  2161. return;
  2162. }
  2163. rtl_l2_data_process(buffer, count, 1);
  2164. //u16 handle, total_len, pdu_len, channel_ID, command_len, psm, scid,
  2165. // dcid, result, status;
  2166. //u8 flag, code, identifier;
  2167. //u8 *pp = (u8 *) (skb->data);
  2168. //STREAM_TO_UINT16(handle, pp);
  2169. //flag = handle >> 12;
  2170. //handle = handle & 0x0FFF;
  2171. //STREAM_TO_UINT16(total_len, pp);
  2172. //STREAM_TO_UINT16(pdu_len, pp);
  2173. //STREAM_TO_UINT16(channel_ID, pp);
  2174. //if (channel_ID == 0x0001) {
  2175. // code = *pp++;
  2176. // switch (code) {
  2177. // case L2CAP_CONN_REQ:
  2178. // identifier = *pp++;
  2179. // STREAM_TO_UINT16(command_len, pp);
  2180. // STREAM_TO_UINT16(psm, pp);
  2181. // STREAM_TO_UINT16(scid, pp);
  2182. // RTKBT_DBG("TX l2cap conn req, hndl %x, PSM %x, scid=%x",
  2183. // handle, psm, scid);
  2184. // handle_l2cap_con_req(handle, psm, scid, 1);
  2185. // break;
  2186. // case L2CAP_CONN_RSP:
  2187. // identifier = *pp++;
  2188. // STREAM_TO_UINT16(command_len, pp);
  2189. // STREAM_TO_UINT16(dcid, pp);
  2190. // STREAM_TO_UINT16(scid, pp);
  2191. // STREAM_TO_UINT16(result, pp);
  2192. // STREAM_TO_UINT16(status, pp);
  2193. // RTKBT_DBG("TX l2cap conn rsp, hndl %x, dcid %x, "
  2194. // "scid %x, result %x",
  2195. // handle, dcid, scid, result);
  2196. // handle_l2cap_con_rsp(handle, dcid, scid, 1, result);
  2197. // break;
  2198. // case L2CAP_DISCONN_REQ:
  2199. // identifier = *pp++;
  2200. // STREAM_TO_UINT16(command_len, pp);
  2201. // STREAM_TO_UINT16(dcid, pp);
  2202. // STREAM_TO_UINT16(scid, pp);
  2203. // RTKBT_DBG("TX l2cap disconn req, hndl %x, dcid %x, "
  2204. // "scid %x", handle, dcid, scid);
  2205. // handle_l2cap_discon_req(handle, dcid, scid, 1);
  2206. // break;
  2207. // case L2CAP_DISCONN_RSP:
  2208. // break;
  2209. // default:
  2210. // break;
  2211. // }
  2212. //} else {
  2213. // if ((flag != 0x01) && (is_profile_connected(profile_a2dp) || is_profile_connected(profile_pan))) //Do not count the continuous packets
  2214. // packets_count(handle, channel_ID, pdu_len, 1, pp);
  2215. //}
  2216. }
  2217. void rtk_btcoex_parse_l2cap_data_rx(uint8_t *buffer, int count)
  2218. {
  2219. if (!test_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
  2220. RTKBT_INFO("%s: Coex is closed, ignore", __func__);
  2221. return;
  2222. }
  2223. rtl_l2_data_process(buffer, count, 0);
  2224. //u16 handle, total_len, pdu_len, channel_ID, command_len, psm, scid,
  2225. // dcid, result, status;
  2226. //u8 flag, code, identifier;
  2227. //u8 *pp = urb->transfer_buffer;
  2228. //STREAM_TO_UINT16(handle, pp);
  2229. //flag = handle >> 12;
  2230. //handle = handle & 0x0FFF;
  2231. //STREAM_TO_UINT16(total_len, pp);
  2232. //STREAM_TO_UINT16(pdu_len, pp);
  2233. //STREAM_TO_UINT16(channel_ID, pp);
  2234. //if (channel_ID == 0x0001) {
  2235. // code = *pp++;
  2236. // switch (code) {
  2237. // case L2CAP_CONN_REQ:
  2238. // identifier = *pp++;
  2239. // STREAM_TO_UINT16(command_len, pp);
  2240. // STREAM_TO_UINT16(psm, pp);
  2241. // STREAM_TO_UINT16(scid, pp);
  2242. // RTKBT_DBG("RX l2cap conn req, hndl %x, PSM %x, scid %x",
  2243. // handle, psm, scid);
  2244. // handle_l2cap_con_req(handle, psm, scid, 0);
  2245. // break;
  2246. // case L2CAP_CONN_RSP:
  2247. // identifier = *pp++;
  2248. // STREAM_TO_UINT16(command_len, pp);
  2249. // STREAM_TO_UINT16(dcid, pp);
  2250. // STREAM_TO_UINT16(scid, pp);
  2251. // STREAM_TO_UINT16(result, pp);
  2252. // STREAM_TO_UINT16(status, pp);
  2253. // RTKBT_DBG("RX l2cap conn rsp, hndl %x, dcid %x, "
  2254. // "scid %x, result %x",
  2255. // handle, dcid, scid, result);
  2256. // handle_l2cap_con_rsp(handle, dcid, scid, 0, result);
  2257. // break;
  2258. // case L2CAP_DISCONN_REQ:
  2259. // identifier = *pp++;
  2260. // STREAM_TO_UINT16(command_len, pp);
  2261. // STREAM_TO_UINT16(dcid, pp);
  2262. // STREAM_TO_UINT16(scid, pp);
  2263. // RTKBT_DBG("RX l2cap disconn req, hndl %x, dcid %x, "
  2264. // "scid %x", handle, dcid, scid);
  2265. // handle_l2cap_discon_req(handle, dcid, scid, 0);
  2266. // break;
  2267. // case L2CAP_DISCONN_RSP:
  2268. // break;
  2269. // default:
  2270. // break;
  2271. // }
  2272. //} else {
  2273. // if ((flag != 0x01) && (is_profile_connected(profile_a2dp) || is_profile_connected(profile_pan))) //Do not count the continuous packets
  2274. // packets_count(handle, channel_ID, pdu_len, 0, pp);
  2275. //}
  2276. }
  2277. #ifdef RTB_SOFTWARE_MAILBOX
  2278. #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
  2279. static void polling_bt_info(struct timer_list *unused)
  2280. #else
  2281. static void polling_bt_info(unsigned long data)
  2282. #endif
  2283. {
  2284. uint8_t temp_cmd[1];
  2285. RTKBT_DBG("polling timer");
  2286. if (btrtl_coex.polling_enable) {
  2287. //temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO;
  2288. temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_STATUS_INFO;
  2289. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 1, temp_cmd);
  2290. }
  2291. mod_timer(&btrtl_coex.polling_timer,
  2292. jiffies + msecs_to_jiffies(1000 * btrtl_coex.polling_interval));
  2293. }
  2294. static void rtk_handle_bt_info_control(uint8_t *p)
  2295. {
  2296. uint8_t temp_cmd[20];
  2297. struct rtl_btinfo_ctl *ctl = (struct rtl_btinfo_ctl*)p;
  2298. RTKBT_DBG("Received polling_enable %u, polling_time %u, "
  2299. "autoreport_enable %u", ctl->polling_enable,
  2300. ctl->polling_time, ctl->autoreport_enable);
  2301. RTKBT_DBG("coex: original polling_enable %u",
  2302. btrtl_coex.polling_enable);
  2303. if (ctl->polling_enable && !btrtl_coex.polling_enable) {
  2304. /* setup polling timer for getting bt info from firmware */
  2305. btrtl_coex.polling_timer.expires =
  2306. jiffies + msecs_to_jiffies(ctl->polling_time * 1000);
  2307. mod_timer(&btrtl_coex.polling_timer,
  2308. btrtl_coex.polling_timer.expires);
  2309. }
  2310. /* Close bt info polling timer */
  2311. if (!ctl->polling_enable && btrtl_coex.polling_enable)
  2312. del_timer(&btrtl_coex.polling_timer);
  2313. if (btrtl_coex.autoreport != ctl->autoreport_enable) {
  2314. temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_ENABLE;
  2315. temp_cmd[1] = 1;
  2316. temp_cmd[2] = ctl->autoreport_enable;
  2317. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
  2318. }
  2319. btrtl_coex.polling_enable = ctl->polling_enable;
  2320. btrtl_coex.polling_interval = ctl->polling_time;
  2321. btrtl_coex.autoreport = ctl->autoreport_enable;
  2322. rtk_notify_info_to_wifi(HOST_RESPONSE, 0, NULL);
  2323. }
  2324. static void rtk_handle_bt_coex_control(uint8_t * p)
  2325. {
  2326. uint8_t temp_cmd[20];
  2327. uint8_t opcode, opcode_len, value, power_decrease, psd_mode,
  2328. access_type;
  2329. opcode = *p++;
  2330. RTKBT_DBG("receive bt coex control event from wifi, op 0x%02x", opcode);
  2331. switch (opcode) {
  2332. case BT_PATCH_VERSION_QUERY:
  2333. rtk_notify_btpatch_version_to_wifi();
  2334. break;
  2335. case IGNORE_WLAN_ACTIVE_CONTROL:
  2336. opcode_len = *p++;
  2337. value = *p++;
  2338. temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_ENABLE_IGNORE_WLAN_ACT_CMD;
  2339. temp_cmd[1] = 1;
  2340. temp_cmd[2] = value;
  2341. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
  2342. break;
  2343. case LNA_CONSTRAIN_CONTROL:
  2344. opcode_len = *p++;
  2345. value = *p++;
  2346. temp_cmd[0] = HCI_VENDOR_SUB_CMD_SET_BT_LNA_CONSTRAINT;
  2347. temp_cmd[1] = 1;
  2348. temp_cmd[2] = value;
  2349. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
  2350. break;
  2351. case BT_POWER_DECREASE_CONTROL:
  2352. opcode_len = *p++;
  2353. power_decrease = *p++;
  2354. temp_cmd[0] = HCI_VENDOR_SUB_CMD_WIFI_FORCE_TX_POWER_CMD;
  2355. temp_cmd[1] = 1;
  2356. temp_cmd[2] = power_decrease;
  2357. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
  2358. break;
  2359. case BT_PSD_MODE_CONTROL:
  2360. opcode_len = *p++;
  2361. psd_mode = *p++;
  2362. temp_cmd[0] = HCI_VENDOR_SUB_CMD_SET_BT_PSD_MODE;
  2363. temp_cmd[1] = 1;
  2364. temp_cmd[2] = psd_mode;
  2365. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
  2366. break;
  2367. case WIFI_BW_CHNL_NOTIFY:
  2368. opcode_len = *p++;
  2369. temp_cmd[0] = HCI_VENDOR_SUB_CMD_WIFI_CHANNEL_AND_BANDWIDTH_CMD;
  2370. temp_cmd[1] = 3;
  2371. memcpy(temp_cmd + 2, p, 3); //wifi_state, wifi_centralchannel, chnnels_btnotuse
  2372. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 5, temp_cmd);
  2373. break;
  2374. case QUERY_BT_AFH_MAP:
  2375. opcode_len = *p++;
  2376. btrtl_coex.piconet_id = *p++;
  2377. btrtl_coex.mode = *p++;
  2378. temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_L;
  2379. temp_cmd[1] = 2;
  2380. temp_cmd[2] = btrtl_coex.piconet_id;
  2381. temp_cmd[3] = btrtl_coex.mode;
  2382. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4, temp_cmd);
  2383. break;
  2384. case BT_REGISTER_ACCESS:
  2385. opcode_len = *p++;
  2386. access_type = *p++;
  2387. if (access_type == 0) { //read
  2388. temp_cmd[0] = HCI_VENDOR_SUB_CMD_RD_REG_REQ;
  2389. temp_cmd[1] = 5;
  2390. temp_cmd[2] = *p++;
  2391. memcpy(temp_cmd + 3, p, 4);
  2392. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 7,
  2393. temp_cmd);
  2394. } else { //write
  2395. temp_cmd[0] = HCI_VENDOR_SUB_CMD_RD_REG_REQ;
  2396. temp_cmd[1] = 5;
  2397. temp_cmd[2] = *p++;
  2398. memcpy(temp_cmd + 3, p, 8);
  2399. rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 11,
  2400. temp_cmd);
  2401. }
  2402. break;
  2403. default:
  2404. break;
  2405. }
  2406. }
  2407. static void rtk_handle_event_from_wifi(uint8_t * msg)
  2408. {
  2409. uint8_t *p = msg;
  2410. uint8_t event_code = *p++;
  2411. uint8_t total_length;
  2412. uint8_t extension_event;
  2413. uint8_t operation;
  2414. uint16_t wifi_opcode;
  2415. uint8_t op_status;
  2416. if (memcmp(msg, invite_rsp, sizeof(invite_rsp)) == 0) {
  2417. RTKBT_DBG("receive invite rsp from wifi, wifi is already on");
  2418. btrtl_coex.wifi_on = 1;
  2419. rtk_notify_extension_version_to_wifi();
  2420. }
  2421. if (memcmp(msg, attend_req, sizeof(attend_req)) == 0) {
  2422. RTKBT_DBG("receive attend req from wifi, wifi turn on");
  2423. btrtl_coex.wifi_on = 1;
  2424. rtkbt_coexmsg_send(attend_ack, sizeof(attend_ack));
  2425. rtk_notify_extension_version_to_wifi();
  2426. }
  2427. if (memcmp(msg, wifi_leave, sizeof(wifi_leave)) == 0) {
  2428. RTKBT_DBG("receive wifi leave from wifi, wifi turn off");
  2429. btrtl_coex.wifi_on = 0;
  2430. rtkbt_coexmsg_send(leave_ack, sizeof(leave_ack));
  2431. if (btrtl_coex.polling_enable) {
  2432. btrtl_coex.polling_enable = 0;
  2433. del_timer(&btrtl_coex.polling_timer);
  2434. }
  2435. }
  2436. if (memcmp(msg, leave_ack, sizeof(leave_ack)) == 0) {
  2437. RTKBT_DBG("receive leave ack from wifi");
  2438. }
  2439. if (event_code == 0xFE) {
  2440. total_length = *p++;
  2441. extension_event = *p++;
  2442. switch (extension_event) {
  2443. case RTK_HS_EXTENSION_EVENT_WIFI_SCAN:
  2444. operation = *p;
  2445. RTKBT_DBG("Recv WiFi scan notify event from WiFi, "
  2446. "op 0x%02x", operation);
  2447. break;
  2448. case RTK_HS_EXTENSION_EVENT_HCI_BT_INFO_CONTROL:
  2449. rtk_handle_bt_info_control(p);
  2450. break;
  2451. case RTK_HS_EXTENSION_EVENT_HCI_BT_COEX_CONTROL:
  2452. rtk_handle_bt_coex_control(p);
  2453. break;
  2454. default:
  2455. break;
  2456. }
  2457. }
  2458. if (event_code == 0x0E) {
  2459. p += 2; //length, number of complete packets
  2460. STREAM_TO_UINT16(wifi_opcode, p);
  2461. op_status = *p;
  2462. RTKBT_DBG("Recv cmd complete event from WiFi, op 0x%02x, "
  2463. "status 0x%02x", wifi_opcode, op_status);
  2464. }
  2465. }
  2466. #endif /* RTB_SOFTWARE_MAILBOX */
  2467. static inline void rtl_free_frags(struct rtl_coex_struct *coex)
  2468. {
  2469. unsigned long flags;
  2470. spin_lock_irqsave(&coex->rxlock, flags);
  2471. coex->elen = 0;
  2472. coex->tbuff = NULL;
  2473. spin_unlock_irqrestore(&coex->rxlock, flags);
  2474. }
  2475. void rtk_btcoex_open(struct hci_dev *hdev)
  2476. {
  2477. if (test_and_set_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
  2478. RTKBT_WARN("RTL COEX is already running.");
  2479. return;
  2480. }
  2481. RTKBT_INFO("Open BTCOEX");
  2482. /* Just for test */
  2483. //struct rtl_btinfo_ctl ctl;
  2484. INIT_DELAYED_WORK(&btrtl_coex.fw_work, (void *)rtl_ev_work);
  2485. #ifdef RTB_SOFTWARE_MAILBOX
  2486. #ifdef RTK_COEX_OVER_SYMBOL
  2487. INIT_WORK(&rtw_work, rtw_work_func);
  2488. skb_queue_head_init(&rtw_q);
  2489. rtw_coex_on = 1;
  2490. #else
  2491. INIT_DELAYED_WORK(&btrtl_coex.sock_work,
  2492. (void *)udpsocket_recv_data);
  2493. #endif
  2494. #endif /* RTB_SOFTWARE_MAILBOX */
  2495. INIT_DELAYED_WORK(&btrtl_coex.l2_work, (void *)rtl_l2_work);
  2496. #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
  2497. #ifdef RTB_SOFTWARE_MAILBOX
  2498. timer_setup(&btrtl_coex.polling_timer, polling_bt_info, 0);
  2499. #endif
  2500. timer_setup(&btrtl_coex.a2dp_count_timer, count_a2dp_packet_timeout, 0);
  2501. timer_setup(&btrtl_coex.pan_count_timer, count_pan_packet_timeout, 0);
  2502. timer_setup(&btrtl_coex.hogp_count_timer, count_hogp_packet_timeout, 0);
  2503. #else
  2504. #ifdef RTB_SOFTWARE_MAILBOX
  2505. setup_timer(&btrtl_coex.polling_timer, polling_bt_info, 0);
  2506. #endif
  2507. setup_timer(&btrtl_coex.a2dp_count_timer, count_a2dp_packet_timeout, 0);
  2508. setup_timer(&btrtl_coex.pan_count_timer, count_pan_packet_timeout, 0);
  2509. setup_timer(&btrtl_coex.hogp_count_timer, count_hogp_packet_timeout, 0);
  2510. #endif
  2511. btrtl_coex.hdev = hdev;
  2512. #ifdef RTB_SOFTWARE_MAILBOX
  2513. btrtl_coex.wifi_on = 0;
  2514. #endif
  2515. init_profile_hash(&btrtl_coex);
  2516. init_connection_hash(&btrtl_coex);
  2517. btrtl_coex.pkt_type = 0;
  2518. btrtl_coex.expect = 0;
  2519. btrtl_coex.elen = 0;
  2520. btrtl_coex.tbuff = NULL;
  2521. #ifdef RTB_SOFTWARE_MAILBOX
  2522. #ifndef RTK_COEX_OVER_SYMBOL
  2523. create_udpsocket();
  2524. #endif
  2525. rtkbt_coexmsg_send(invite_req, sizeof(invite_req));
  2526. #endif
  2527. /* Just for test */
  2528. //ctl.polling_enable = 1;
  2529. //ctl.polling_time = 1;
  2530. //ctl.autoreport_enable = 1;
  2531. //rtk_handle_bt_info_control((u8 *)&ctl);
  2532. }
  2533. void rtk_btcoex_close(void)
  2534. {
  2535. int kk = 0;
  2536. if (!test_and_clear_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
  2537. RTKBT_WARN("RTL COEX is already closed.");
  2538. return;
  2539. }
  2540. RTKBT_INFO("Close BTCOEX");
  2541. #ifdef RTB_SOFTWARE_MAILBOX
  2542. /* Close coex socket */
  2543. if (btrtl_coex.wifi_on)
  2544. rtkbt_coexmsg_send(bt_leave, sizeof(bt_leave));
  2545. #ifdef RTK_COEX_OVER_SYMBOL
  2546. rtw_coex_on = 0;
  2547. skb_queue_purge(&rtw_q);
  2548. cancel_work_sync(&rtw_work);
  2549. #else
  2550. cancel_delayed_work_sync(&btrtl_coex.sock_work);
  2551. if (btrtl_coex.sock_open) {
  2552. btrtl_coex.sock_open = 0;
  2553. RTKBT_DBG("release udp socket");
  2554. sock_release(btrtl_coex.udpsock);
  2555. }
  2556. #endif
  2557. /* Delete all timers */
  2558. if (btrtl_coex.polling_enable) {
  2559. btrtl_coex.polling_enable = 0;
  2560. del_timer_sync(&(btrtl_coex.polling_timer));
  2561. }
  2562. #endif /* RTB_SOFTWARE_MAILBOX */
  2563. del_timer_sync(&btrtl_coex.a2dp_count_timer);
  2564. del_timer_sync(&btrtl_coex.pan_count_timer);
  2565. del_timer_sync(&btrtl_coex.hogp_count_timer);
  2566. cancel_delayed_work_sync(&btrtl_coex.fw_work);
  2567. cancel_delayed_work_sync(&btrtl_coex.l2_work);
  2568. flush_connection_hash(&btrtl_coex);
  2569. flush_profile_hash(&btrtl_coex);
  2570. btrtl_coex.profile_bitmap = 0;
  2571. btrtl_coex.profile_status = 0;
  2572. for (kk = 0; kk < 8; kk++)
  2573. btrtl_coex.profile_refcount[kk] = 0;
  2574. rtl_free_frags(&btrtl_coex);
  2575. RTKBT_DBG("-x");
  2576. }
  2577. void rtk_btcoex_probe(struct hci_dev *hdev)
  2578. {
  2579. btrtl_coex.hdev = hdev;
  2580. spin_lock_init(&btrtl_coex.spin_lock_sock);
  2581. spin_lock_init(&btrtl_coex.spin_lock_profile);
  2582. }
  2583. void rtk_btcoex_init(void)
  2584. {
  2585. RTKBT_DBG("%s: version: %s", __func__, RTK_VERSION);
  2586. RTKBT_DBG("create workqueue");
  2587. #ifdef RTB_SOFTWARE_MAILBOX
  2588. #ifdef RTK_COEX_OVER_SYMBOL
  2589. RTKBT_INFO("Coex over Symbol");
  2590. rtw_wq = create_workqueue("btcoexwork");
  2591. skb_queue_head_init(&rtw_q);
  2592. #else
  2593. RTKBT_INFO("Coex over UDP");
  2594. btrtl_coex.sock_wq = create_workqueue("btudpwork");
  2595. #endif
  2596. #endif /* RTB_SOFTWARE_MAILBOX */
  2597. btrtl_coex.fw_wq = create_workqueue("btfwwork");
  2598. rtl_alloc_buff(&btrtl_coex);
  2599. spin_lock_init(&btrtl_coex.rxlock);
  2600. }
  2601. void rtk_btcoex_exit(void)
  2602. {
  2603. RTKBT_DBG("%s: destroy workqueue", __func__);
  2604. #ifdef RTB_SOFTWARE_MAILBOX
  2605. #ifdef RTK_COEX_OVER_SYMBOL
  2606. flush_workqueue(rtw_wq);
  2607. destroy_workqueue(rtw_wq);
  2608. #else
  2609. flush_workqueue(btrtl_coex.sock_wq);
  2610. destroy_workqueue(btrtl_coex.sock_wq);
  2611. #endif
  2612. #endif
  2613. flush_workqueue(btrtl_coex.fw_wq);
  2614. destroy_workqueue(btrtl_coex.fw_wq);
  2615. rtl_free_buff(&btrtl_coex);
  2616. }