ar9003_mci.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399
  1. /*
  2. * Copyright (c) 2008-2011 Atheros Communications Inc.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <linux/export.h>
  17. #include "hw.h"
  18. #include "hw-ops.h"
  19. #include "ar9003_phy.h"
  20. #include "ar9003_mci.h"
  21. static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah)
  22. {
  23. REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
  24. AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1);
  25. udelay(1);
  26. REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
  27. AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 0);
  28. }
  29. static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address,
  30. u32 bit_position, int time_out)
  31. {
  32. struct ath_common *common = ath9k_hw_common(ah);
  33. while (time_out) {
  34. if (REG_READ(ah, address) & bit_position) {
  35. REG_WRITE(ah, address, bit_position);
  36. if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) {
  37. if (bit_position &
  38. AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
  39. ar9003_mci_reset_req_wakeup(ah);
  40. if (bit_position &
  41. (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING |
  42. AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING))
  43. REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
  44. AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
  45. REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
  46. AR_MCI_INTERRUPT_RX_MSG);
  47. }
  48. break;
  49. }
  50. udelay(10);
  51. time_out -= 10;
  52. if (time_out < 0)
  53. break;
  54. }
  55. if (time_out <= 0) {
  56. ath_dbg(common, MCI,
  57. "MCI Wait for Reg 0x%08x = 0x%08x timeout\n",
  58. address, bit_position);
  59. ath_dbg(common, MCI,
  60. "MCI INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n",
  61. REG_READ(ah, AR_MCI_INTERRUPT_RAW),
  62. REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
  63. time_out = 0;
  64. }
  65. return time_out;
  66. }
  67. static void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done)
  68. {
  69. u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
  70. ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16,
  71. wait_done, false);
  72. udelay(5);
  73. }
  74. static void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done)
  75. {
  76. u32 payload = 0x00000000;
  77. ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1,
  78. wait_done, false);
  79. }
  80. static void ar9003_mci_send_req_wake(struct ath_hw *ah, bool wait_done)
  81. {
  82. ar9003_mci_send_message(ah, MCI_REQ_WAKE, MCI_FLAG_DISABLE_TIMESTAMP,
  83. NULL, 0, wait_done, false);
  84. udelay(5);
  85. }
  86. static void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done)
  87. {
  88. ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP,
  89. NULL, 0, wait_done, false);
  90. }
  91. static void ar9003_mci_send_lna_take(struct ath_hw *ah, bool wait_done)
  92. {
  93. u32 payload = 0x70000000;
  94. ar9003_mci_send_message(ah, MCI_LNA_TAKE, 0, &payload, 1,
  95. wait_done, false);
  96. }
  97. static void ar9003_mci_send_sys_sleeping(struct ath_hw *ah, bool wait_done)
  98. {
  99. ar9003_mci_send_message(ah, MCI_SYS_SLEEPING,
  100. MCI_FLAG_DISABLE_TIMESTAMP,
  101. NULL, 0, wait_done, false);
  102. }
  103. static void ar9003_mci_send_coex_version_query(struct ath_hw *ah,
  104. bool wait_done)
  105. {
  106. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  107. u32 payload[4] = {0, 0, 0, 0};
  108. if (!mci->bt_version_known &&
  109. (mci->bt_state != MCI_BT_SLEEP)) {
  110. MCI_GPM_SET_TYPE_OPCODE(payload,
  111. MCI_GPM_COEX_AGENT,
  112. MCI_GPM_COEX_VERSION_QUERY);
  113. ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
  114. wait_done, true);
  115. }
  116. }
  117. static void ar9003_mci_send_coex_version_response(struct ath_hw *ah,
  118. bool wait_done)
  119. {
  120. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  121. u32 payload[4] = {0, 0, 0, 0};
  122. MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
  123. MCI_GPM_COEX_VERSION_RESPONSE);
  124. *(((u8 *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) =
  125. mci->wlan_ver_major;
  126. *(((u8 *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) =
  127. mci->wlan_ver_minor;
  128. ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
  129. }
  130. static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah,
  131. bool wait_done)
  132. {
  133. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  134. u32 *payload = &mci->wlan_channels[0];
  135. if ((mci->wlan_channels_update == true) &&
  136. (mci->bt_state != MCI_BT_SLEEP)) {
  137. MCI_GPM_SET_TYPE_OPCODE(payload,
  138. MCI_GPM_COEX_AGENT,
  139. MCI_GPM_COEX_WLAN_CHANNELS);
  140. ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
  141. wait_done, true);
  142. MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff);
  143. }
  144. }
  145. static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah,
  146. bool wait_done, u8 query_type)
  147. {
  148. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  149. u32 payload[4] = {0, 0, 0, 0};
  150. bool query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO |
  151. MCI_GPM_COEX_QUERY_BT_TOPOLOGY));
  152. if (mci->bt_state != MCI_BT_SLEEP) {
  153. MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
  154. MCI_GPM_COEX_STATUS_QUERY);
  155. *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type;
  156. /*
  157. * If bt_status_query message is not sent successfully,
  158. * then need_flush_btinfo should be set again.
  159. */
  160. if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
  161. wait_done, true)) {
  162. if (query_btinfo)
  163. mci->need_flush_btinfo = true;
  164. }
  165. if (query_btinfo)
  166. mci->query_bt = false;
  167. }
  168. }
  169. static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
  170. bool wait_done)
  171. {
  172. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  173. u32 payload[4] = {0, 0, 0, 0};
  174. MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
  175. MCI_GPM_COEX_HALT_BT_GPM);
  176. if (halt) {
  177. mci->query_bt = true;
  178. /* Send next unhalt no matter halt sent or not */
  179. mci->unhalt_bt_gpm = true;
  180. mci->need_flush_btinfo = true;
  181. *(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
  182. MCI_GPM_COEX_BT_GPM_HALT;
  183. } else
  184. *(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
  185. MCI_GPM_COEX_BT_GPM_UNHALT;
  186. ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
  187. }
  188. static void ar9003_mci_prep_interface(struct ath_hw *ah)
  189. {
  190. struct ath_common *common = ath9k_hw_common(ah);
  191. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  192. u32 saved_mci_int_en;
  193. u32 mci_timeout = 150;
  194. mci->bt_state = MCI_BT_SLEEP;
  195. saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
  196. REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
  197. REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
  198. REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
  199. REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
  200. REG_READ(ah, AR_MCI_INTERRUPT_RAW));
  201. ar9003_mci_remote_reset(ah, true);
  202. ar9003_mci_send_req_wake(ah, true);
  203. if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
  204. AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) {
  205. mci->bt_state = MCI_BT_AWAKE;
  206. /*
  207. * we don't need to send more remote_reset at this moment.
  208. * If BT receive first remote_reset, then BT HW will
  209. * be cleaned up and will be able to receive req_wake
  210. * and BT HW will respond sys_waking.
  211. * In this case, WLAN will receive BT's HW sys_waking.
  212. * Otherwise, if BT SW missed initial remote_reset,
  213. * that remote_reset will still clean up BT MCI RX,
  214. * and the req_wake will wake BT up,
  215. * and BT SW will respond this req_wake with a remote_reset and
  216. * sys_waking. In this case, WLAN will receive BT's SW
  217. * sys_waking. In either case, BT's RX is cleaned up. So we
  218. * don't need to reply BT's remote_reset now, if any.
  219. * Similarly, if in any case, WLAN can receive BT's sys_waking,
  220. * that means WLAN's RX is also fine.
  221. */
  222. ar9003_mci_send_sys_waking(ah, true);
  223. udelay(10);
  224. /*
  225. * Set BT priority interrupt value to be 0xff to
  226. * avoid having too many BT PRIORITY interrupts.
  227. */
  228. REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF);
  229. REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF);
  230. REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF);
  231. REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF);
  232. REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF);
  233. /*
  234. * A contention reset will be received after send out
  235. * sys_waking. Also BT priority interrupt bits will be set.
  236. * Clear those bits before the next step.
  237. */
  238. REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
  239. AR_MCI_INTERRUPT_RX_MSG_CONT_RST);
  240. REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
  241. AR_MCI_INTERRUPT_BT_PRI);
  242. if (mci->is_2g) {
  243. ar9003_mci_send_lna_transfer(ah, true);
  244. udelay(5);
  245. }
  246. if ((mci->is_2g && !mci->update_2g5g)) {
  247. if (ar9003_mci_wait_for_interrupt(ah,
  248. AR_MCI_INTERRUPT_RX_MSG_RAW,
  249. AR_MCI_INTERRUPT_RX_MSG_LNA_INFO,
  250. mci_timeout))
  251. ath_dbg(common, MCI,
  252. "MCI WLAN has control over the LNA & BT obeys it\n");
  253. else
  254. ath_dbg(common, MCI,
  255. "MCI BT didn't respond to LNA_TRANS\n");
  256. }
  257. }
  258. /* Clear the extra redundant SYS_WAKING from BT */
  259. if ((mci->bt_state == MCI_BT_AWAKE) &&
  260. (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
  261. AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) &&
  262. (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
  263. AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) {
  264. REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
  265. AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING);
  266. REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
  267. AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
  268. }
  269. REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
  270. }
  271. void ar9003_mci_set_full_sleep(struct ath_hw *ah)
  272. {
  273. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  274. if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) &&
  275. (mci->bt_state != MCI_BT_SLEEP) &&
  276. !mci->halted_bt_gpm) {
  277. ar9003_mci_send_coex_halt_bt_gpm(ah, true, true);
  278. }
  279. mci->ready = false;
  280. REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
  281. }
  282. static void ar9003_mci_disable_interrupt(struct ath_hw *ah)
  283. {
  284. REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
  285. REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);
  286. }
  287. static void ar9003_mci_enable_interrupt(struct ath_hw *ah)
  288. {
  289. REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT);
  290. REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN,
  291. AR_MCI_INTERRUPT_RX_MSG_DEFAULT);
  292. }
  293. static bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints)
  294. {
  295. u32 intr;
  296. intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
  297. return ((intr & ints) == ints);
  298. }
  299. void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
  300. u32 *rx_msg_intr)
  301. {
  302. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  303. *raw_intr = mci->raw_intr;
  304. *rx_msg_intr = mci->rx_msg_intr;
  305. /* Clean int bits after the values are read. */
  306. mci->raw_intr = 0;
  307. mci->rx_msg_intr = 0;
  308. }
  309. EXPORT_SYMBOL(ar9003_mci_get_interrupt);
  310. void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
  311. {
  312. struct ath_common *common = ath9k_hw_common(ah);
  313. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  314. u32 raw_intr, rx_msg_intr;
  315. rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
  316. raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW);
  317. if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef)) {
  318. ath_dbg(common, MCI,
  319. "MCI gets 0xdeadbeef during int processing\n");
  320. } else {
  321. mci->rx_msg_intr |= rx_msg_intr;
  322. mci->raw_intr |= raw_intr;
  323. *masked |= ATH9K_INT_MCI;
  324. if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO)
  325. mci->cont_status = REG_READ(ah, AR_MCI_CONT_STATUS);
  326. REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr);
  327. REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr);
  328. }
  329. }
  330. static void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g)
  331. {
  332. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  333. if (!mci->update_2g5g &&
  334. (mci->is_2g != is_2g))
  335. mci->update_2g5g = true;
  336. mci->is_2g = is_2g;
  337. }
  338. static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index)
  339. {
  340. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  341. u32 *payload;
  342. u32 recv_type, offset;
  343. if (msg_index == MCI_GPM_INVALID)
  344. return false;
  345. offset = msg_index << 4;
  346. payload = (u32 *)(mci->gpm_buf + offset);
  347. recv_type = MCI_GPM_TYPE(payload);
  348. if (recv_type == MCI_GPM_RSVD_PATTERN)
  349. return false;
  350. return true;
  351. }
  352. static void ar9003_mci_observation_set_up(struct ath_hw *ah)
  353. {
  354. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  355. if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) {
  356. ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
  357. ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);
  358. ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
  359. ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
  360. } else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_TXRX) {
  361. ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
  362. ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
  363. ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
  364. ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
  365. ath9k_hw_cfg_output(ah, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
  366. } else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_BT) {
  367. ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
  368. ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
  369. ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
  370. ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
  371. } else
  372. return;
  373. REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
  374. REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_DS_JTAG_DISABLE, 1);
  375. REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_WLAN_UART_INTF_EN, 0);
  376. REG_SET_BIT(ah, AR_GLB_GPIO_CONTROL, ATH_MCI_CONFIG_MCI_OBS_GPIO);
  377. REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0);
  378. REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1);
  379. REG_WRITE(ah, AR_OBS, 0x4b);
  380. REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL1, 0x03);
  381. REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL2, 0x01);
  382. REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_LSB, 0x02);
  383. REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_MSB, 0x03);
  384. REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS,
  385. AR_PHY_TEST_CTL_DEBUGPORT_SEL, 0x07);
  386. }
  387. static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done,
  388. u8 opcode, u32 bt_flags)
  389. {
  390. u32 pld[4] = {0, 0, 0, 0};
  391. MCI_GPM_SET_TYPE_OPCODE(pld, MCI_GPM_COEX_AGENT,
  392. MCI_GPM_COEX_BT_UPDATE_FLAGS);
  393. *(((u8 *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP) = opcode;
  394. *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF;
  395. *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 1) = (bt_flags >> 8) & 0xFF;
  396. *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = (bt_flags >> 16) & 0xFF;
  397. *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = (bt_flags >> 24) & 0xFF;
  398. return ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16,
  399. wait_done, true);
  400. }
  401. static void ar9003_mci_sync_bt_state(struct ath_hw *ah)
  402. {
  403. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  404. u32 cur_bt_state;
  405. cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL);
  406. if (mci->bt_state != cur_bt_state)
  407. mci->bt_state = cur_bt_state;
  408. if (mci->bt_state != MCI_BT_SLEEP) {
  409. ar9003_mci_send_coex_version_query(ah, true);
  410. ar9003_mci_send_coex_wlan_channels(ah, true);
  411. if (mci->unhalt_bt_gpm == true)
  412. ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
  413. }
  414. }
  415. void ar9003_mci_check_bt(struct ath_hw *ah)
  416. {
  417. struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
  418. if (!mci_hw->ready)
  419. return;
  420. /*
  421. * check BT state again to make
  422. * sure it's not changed.
  423. */
  424. ar9003_mci_sync_bt_state(ah);
  425. ar9003_mci_2g5g_switch(ah, true);
  426. if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
  427. (mci_hw->query_bt == true)) {
  428. mci_hw->need_flush_btinfo = true;
  429. }
  430. }
  431. static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type,
  432. u8 gpm_opcode, u32 *p_gpm)
  433. {
  434. struct ath_common *common = ath9k_hw_common(ah);
  435. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  436. u8 *p_data = (u8 *) p_gpm;
  437. if (gpm_type != MCI_GPM_COEX_AGENT)
  438. return;
  439. switch (gpm_opcode) {
  440. case MCI_GPM_COEX_VERSION_QUERY:
  441. ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n");
  442. ar9003_mci_send_coex_version_response(ah, true);
  443. break;
  444. case MCI_GPM_COEX_VERSION_RESPONSE:
  445. ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n");
  446. mci->bt_ver_major =
  447. *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION);
  448. mci->bt_ver_minor =
  449. *(p_data + MCI_GPM_COEX_B_MINOR_VERSION);
  450. mci->bt_version_known = true;
  451. ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n",
  452. mci->bt_ver_major, mci->bt_ver_minor);
  453. break;
  454. case MCI_GPM_COEX_STATUS_QUERY:
  455. ath_dbg(common, MCI,
  456. "MCI Recv GPM COEX Status Query = 0x%02X\n",
  457. *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP));
  458. mci->wlan_channels_update = true;
  459. ar9003_mci_send_coex_wlan_channels(ah, true);
  460. break;
  461. case MCI_GPM_COEX_BT_PROFILE_INFO:
  462. mci->query_bt = true;
  463. ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n");
  464. break;
  465. case MCI_GPM_COEX_BT_STATUS_UPDATE:
  466. mci->query_bt = true;
  467. ath_dbg(common, MCI,
  468. "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
  469. *(p_gpm + 3));
  470. break;
  471. default:
  472. break;
  473. }
  474. }
  475. static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
  476. u8 gpm_opcode, int time_out)
  477. {
  478. struct ath_common *common = ath9k_hw_common(ah);
  479. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  480. u32 *p_gpm = NULL, mismatch = 0, more_data;
  481. u32 offset;
  482. u8 recv_type = 0, recv_opcode = 0;
  483. bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);
  484. more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE;
  485. while (time_out > 0) {
  486. if (p_gpm) {
  487. MCI_GPM_RECYCLE(p_gpm);
  488. p_gpm = NULL;
  489. }
  490. if (more_data != MCI_GPM_MORE)
  491. time_out = ar9003_mci_wait_for_interrupt(ah,
  492. AR_MCI_INTERRUPT_RX_MSG_RAW,
  493. AR_MCI_INTERRUPT_RX_MSG_GPM,
  494. time_out);
  495. if (!time_out)
  496. break;
  497. offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
  498. &more_data);
  499. if (offset == MCI_GPM_INVALID)
  500. continue;
  501. p_gpm = (u32 *) (mci->gpm_buf + offset);
  502. recv_type = MCI_GPM_TYPE(p_gpm);
  503. recv_opcode = MCI_GPM_OPCODE(p_gpm);
  504. if (MCI_GPM_IS_CAL_TYPE(recv_type)) {
  505. if (recv_type == gpm_type) {
  506. if ((gpm_type == MCI_GPM_BT_CAL_DONE) &&
  507. !b_is_bt_cal_done) {
  508. gpm_type = MCI_GPM_BT_CAL_GRANT;
  509. continue;
  510. }
  511. break;
  512. }
  513. } else if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) {
  514. break;
  515. }
  516. /*
  517. * check if it's cal_grant
  518. *
  519. * When we're waiting for cal_grant in reset routine,
  520. * it's possible that BT sends out cal_request at the
  521. * same time. Since BT's calibration doesn't happen
  522. * that often, we'll let BT completes calibration then
  523. * we continue to wait for cal_grant from BT.
  524. * Orginal: Wait BT_CAL_GRANT.
  525. * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
  526. * BT_CAL_DONE -> Wait BT_CAL_GRANT.
  527. */
  528. if ((gpm_type == MCI_GPM_BT_CAL_GRANT) &&
  529. (recv_type == MCI_GPM_BT_CAL_REQ)) {
  530. u32 payload[4] = {0, 0, 0, 0};
  531. gpm_type = MCI_GPM_BT_CAL_DONE;
  532. MCI_GPM_SET_CAL_TYPE(payload,
  533. MCI_GPM_WLAN_CAL_GRANT);
  534. ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
  535. false, false);
  536. continue;
  537. } else {
  538. ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n",
  539. *(p_gpm + 1));
  540. mismatch++;
  541. ar9003_mci_process_gpm_extra(ah, recv_type,
  542. recv_opcode, p_gpm);
  543. }
  544. }
  545. if (p_gpm) {
  546. MCI_GPM_RECYCLE(p_gpm);
  547. p_gpm = NULL;
  548. }
  549. if (time_out <= 0)
  550. time_out = 0;
  551. while (more_data == MCI_GPM_MORE) {
  552. offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
  553. &more_data);
  554. if (offset == MCI_GPM_INVALID)
  555. break;
  556. p_gpm = (u32 *) (mci->gpm_buf + offset);
  557. recv_type = MCI_GPM_TYPE(p_gpm);
  558. recv_opcode = MCI_GPM_OPCODE(p_gpm);
  559. if (!MCI_GPM_IS_CAL_TYPE(recv_type))
  560. ar9003_mci_process_gpm_extra(ah, recv_type,
  561. recv_opcode, p_gpm);
  562. MCI_GPM_RECYCLE(p_gpm);
  563. }
  564. return time_out;
  565. }
  566. bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
  567. {
  568. struct ath_common *common = ath9k_hw_common(ah);
  569. struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
  570. u32 payload[4] = {0, 0, 0, 0};
  571. ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));
  572. if (mci_hw->bt_state != MCI_BT_CAL_START)
  573. return false;
  574. mci_hw->bt_state = MCI_BT_CAL;
  575. /*
  576. * MCI FIX: disable mci interrupt here. This is to avoid
  577. * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
  578. * lead to mci_intr reentry.
  579. */
  580. ar9003_mci_disable_interrupt(ah);
  581. MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
  582. ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
  583. 16, true, false);
  584. /* Wait BT calibration to be completed for 25ms */
  585. if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
  586. 0, 25000))
  587. ath_dbg(common, MCI, "MCI BT_CAL_DONE received\n");
  588. else
  589. ath_dbg(common, MCI,
  590. "MCI BT_CAL_DONE not received\n");
  591. mci_hw->bt_state = MCI_BT_AWAKE;
  592. /* MCI FIX: enable mci interrupt here */
  593. ar9003_mci_enable_interrupt(ah);
  594. return true;
  595. }
  596. int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
  597. struct ath9k_hw_cal_data *caldata)
  598. {
  599. struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
  600. if (!mci_hw->ready)
  601. return 0;
  602. if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP))
  603. goto exit;
  604. if (ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
  605. ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) {
  606. /*
  607. * BT is sleeping. Check if BT wakes up during
  608. * WLAN calibration. If BT wakes up during
  609. * WLAN calibration, need to go through all
  610. * message exchanges again and recal.
  611. */
  612. REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
  613. AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
  614. AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
  615. ar9003_mci_remote_reset(ah, true);
  616. ar9003_mci_send_sys_waking(ah, true);
  617. udelay(1);
  618. if (IS_CHAN_2GHZ(chan))
  619. ar9003_mci_send_lna_transfer(ah, true);
  620. mci_hw->bt_state = MCI_BT_AWAKE;
  621. if (caldata) {
  622. caldata->done_txiqcal_once = false;
  623. caldata->done_txclcal_once = false;
  624. caldata->rtt_hist.num_readings = 0;
  625. }
  626. if (!ath9k_hw_init_cal(ah, chan))
  627. return -EIO;
  628. }
  629. exit:
  630. ar9003_mci_enable_interrupt(ah);
  631. return 0;
  632. }
  633. static void ar9003_mci_mute_bt(struct ath_hw *ah)
  634. {
  635. /* disable all MCI messages */
  636. REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
  637. REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
  638. REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
  639. REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
  640. REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
  641. REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
  642. /* wait pending HW messages to flush out */
  643. udelay(10);
  644. /*
  645. * Send LNA_TAKE and SYS_SLEEPING when
  646. * 1. reset not after resuming from full sleep
  647. * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
  648. */
  649. ar9003_mci_send_lna_take(ah, true);
  650. udelay(5);
  651. ar9003_mci_send_sys_sleeping(ah, true);
  652. }
  653. static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable)
  654. {
  655. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  656. u32 thresh;
  657. if (enable) {
  658. REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
  659. AR_MCI_SCHD_TABLE_2_HW_BASED, 1);
  660. REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
  661. AR_MCI_SCHD_TABLE_2_MEM_BASED, 1);
  662. if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) {
  663. thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH);
  664. REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
  665. AR_BTCOEX_CTRL_AGGR_THRESH, thresh);
  666. REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
  667. AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1);
  668. } else {
  669. REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
  670. AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0);
  671. }
  672. REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
  673. AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
  674. } else {
  675. REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
  676. AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
  677. }
  678. }
  679. void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
  680. bool is_full_sleep)
  681. {
  682. struct ath_common *common = ath9k_hw_common(ah);
  683. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  684. u32 regval;
  685. ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
  686. is_full_sleep, is_2g);
  687. if (!mci->gpm_addr && !mci->sched_addr) {
  688. ath_dbg(common, MCI,
  689. "MCI GPM and schedule buffers are not allocated\n");
  690. return;
  691. }
  692. if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
  693. ath_dbg(common, MCI, "BTCOEX control register is dead\n");
  694. return;
  695. }
  696. /* Program MCI DMA related registers */
  697. REG_WRITE(ah, AR_MCI_GPM_0, mci->gpm_addr);
  698. REG_WRITE(ah, AR_MCI_GPM_1, mci->gpm_len);
  699. REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, mci->sched_addr);
  700. /*
  701. * To avoid MCI state machine be affected by incoming remote MCI msgs,
  702. * MCI mode will be enabled later, right before reset the MCI TX and RX.
  703. */
  704. regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
  705. SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
  706. SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
  707. SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
  708. SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
  709. SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
  710. SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
  711. SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
  712. SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
  713. REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
  714. if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
  715. ar9003_mci_osla_setup(ah, true);
  716. else
  717. ar9003_mci_osla_setup(ah, false);
  718. REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
  719. AR_BTCOEX_CTRL_SPDT_ENABLE);
  720. REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3,
  721. AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20);
  722. REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 1);
  723. REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
  724. regval = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV);
  725. REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval);
  726. REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN);
  727. /* Resetting the Rx and Tx paths of MCI */
  728. regval = REG_READ(ah, AR_MCI_COMMAND2);
  729. regval |= SM(1, AR_MCI_COMMAND2_RESET_TX);
  730. REG_WRITE(ah, AR_MCI_COMMAND2, regval);
  731. udelay(1);
  732. regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX);
  733. REG_WRITE(ah, AR_MCI_COMMAND2, regval);
  734. if (is_full_sleep) {
  735. ar9003_mci_mute_bt(ah);
  736. udelay(100);
  737. }
  738. regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
  739. REG_WRITE(ah, AR_MCI_COMMAND2, regval);
  740. udelay(1);
  741. regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
  742. REG_WRITE(ah, AR_MCI_COMMAND2, regval);
  743. ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
  744. REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
  745. (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
  746. SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));
  747. REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
  748. AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
  749. ar9003_mci_observation_set_up(ah);
  750. mci->ready = true;
  751. ar9003_mci_prep_interface(ah);
  752. if (en_int)
  753. ar9003_mci_enable_interrupt(ah);
  754. }
  755. void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
  756. {
  757. struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
  758. ar9003_mci_disable_interrupt(ah);
  759. if (mci_hw->ready && !save_fullsleep) {
  760. ar9003_mci_mute_bt(ah);
  761. udelay(20);
  762. REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
  763. }
  764. mci_hw->bt_state = MCI_BT_SLEEP;
  765. mci_hw->ready = false;
  766. }
  767. static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done)
  768. {
  769. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  770. u32 new_flags, to_set, to_clear;
  771. if (mci->update_2g5g && (mci->bt_state != MCI_BT_SLEEP)) {
  772. if (mci->is_2g) {
  773. new_flags = MCI_2G_FLAGS;
  774. to_clear = MCI_2G_FLAGS_CLEAR_MASK;
  775. to_set = MCI_2G_FLAGS_SET_MASK;
  776. } else {
  777. new_flags = MCI_5G_FLAGS;
  778. to_clear = MCI_5G_FLAGS_CLEAR_MASK;
  779. to_set = MCI_5G_FLAGS_SET_MASK;
  780. }
  781. if (to_clear)
  782. ar9003_mci_send_coex_bt_flags(ah, wait_done,
  783. MCI_GPM_COEX_BT_FLAGS_CLEAR,
  784. to_clear);
  785. if (to_set)
  786. ar9003_mci_send_coex_bt_flags(ah, wait_done,
  787. MCI_GPM_COEX_BT_FLAGS_SET,
  788. to_set);
  789. }
  790. }
  791. static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header,
  792. u32 *payload, bool queue)
  793. {
  794. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  795. u8 type, opcode;
  796. /* check if the message is to be queued */
  797. if (header != MCI_GPM)
  798. return;
  799. type = MCI_GPM_TYPE(payload);
  800. opcode = MCI_GPM_OPCODE(payload);
  801. if (type != MCI_GPM_COEX_AGENT)
  802. return;
  803. switch (opcode) {
  804. case MCI_GPM_COEX_BT_UPDATE_FLAGS:
  805. if (*(((u8 *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) ==
  806. MCI_GPM_COEX_BT_FLAGS_READ)
  807. break;
  808. mci->update_2g5g = queue;
  809. break;
  810. case MCI_GPM_COEX_WLAN_CHANNELS:
  811. mci->wlan_channels_update = queue;
  812. break;
  813. case MCI_GPM_COEX_HALT_BT_GPM:
  814. if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
  815. MCI_GPM_COEX_BT_GPM_UNHALT) {
  816. mci->unhalt_bt_gpm = queue;
  817. if (!queue)
  818. mci->halted_bt_gpm = false;
  819. }
  820. if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
  821. MCI_GPM_COEX_BT_GPM_HALT) {
  822. mci->halted_bt_gpm = !queue;
  823. }
  824. break;
  825. default:
  826. break;
  827. }
  828. }
  829. void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done)
  830. {
  831. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  832. if (mci->update_2g5g) {
  833. if (mci->is_2g) {
  834. ar9003_mci_send_2g5g_status(ah, true);
  835. ar9003_mci_send_lna_transfer(ah, true);
  836. udelay(5);
  837. REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
  838. AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
  839. REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL,
  840. AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
  841. if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) {
  842. REG_SET_BIT(ah, AR_BTCOEX_CTRL,
  843. AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
  844. }
  845. } else {
  846. ar9003_mci_send_lna_take(ah, true);
  847. udelay(5);
  848. REG_SET_BIT(ah, AR_MCI_TX_CTRL,
  849. AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
  850. REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
  851. AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
  852. REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
  853. AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
  854. ar9003_mci_send_2g5g_status(ah, true);
  855. }
  856. }
  857. }
  858. bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
  859. u32 *payload, u8 len, bool wait_done,
  860. bool check_bt)
  861. {
  862. struct ath_common *common = ath9k_hw_common(ah);
  863. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  864. bool msg_sent = false;
  865. u32 regval;
  866. u32 saved_mci_int_en;
  867. int i;
  868. saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
  869. regval = REG_READ(ah, AR_BTCOEX_CTRL);
  870. if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) {
  871. ath_dbg(common, MCI,
  872. "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
  873. header, (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0);
  874. ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
  875. return false;
  876. } else if (check_bt && (mci->bt_state == MCI_BT_SLEEP)) {
  877. ath_dbg(common, MCI,
  878. "MCI Don't send message 0x%x. BT is in sleep state\n",
  879. header);
  880. ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
  881. return false;
  882. }
  883. if (wait_done)
  884. REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
  885. /* Need to clear SW_MSG_DONE raw bit before wait */
  886. REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
  887. (AR_MCI_INTERRUPT_SW_MSG_DONE |
  888. AR_MCI_INTERRUPT_MSG_FAIL_MASK));
  889. if (payload) {
  890. for (i = 0; (i * 4) < len; i++)
  891. REG_WRITE(ah, (AR_MCI_TX_PAYLOAD0 + i * 4),
  892. *(payload + i));
  893. }
  894. REG_WRITE(ah, AR_MCI_COMMAND0,
  895. (SM((flag & MCI_FLAG_DISABLE_TIMESTAMP),
  896. AR_MCI_COMMAND0_DISABLE_TIMESTAMP) |
  897. SM(len, AR_MCI_COMMAND0_LEN) |
  898. SM(header, AR_MCI_COMMAND0_HEADER)));
  899. if (wait_done &&
  900. !(ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW,
  901. AR_MCI_INTERRUPT_SW_MSG_DONE, 500)))
  902. ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
  903. else {
  904. ar9003_mci_queue_unsent_gpm(ah, header, payload, false);
  905. msg_sent = true;
  906. }
  907. if (wait_done)
  908. REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
  909. return msg_sent;
  910. }
  911. EXPORT_SYMBOL(ar9003_mci_send_message);
  912. void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable)
  913. {
  914. struct ath_common *common = ath9k_hw_common(ah);
  915. struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
  916. u32 pld[4] = {0, 0, 0, 0};
  917. if ((mci_hw->bt_state != MCI_BT_AWAKE) ||
  918. (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL))
  919. return;
  920. MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ);
  921. pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++;
  922. ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
  923. if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) {
  924. ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n");
  925. } else {
  926. is_reusable = false;
  927. ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n");
  928. }
  929. }
  930. void ar9003_mci_init_cal_done(struct ath_hw *ah)
  931. {
  932. struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
  933. u32 pld[4] = {0, 0, 0, 0};
  934. if ((mci_hw->bt_state != MCI_BT_AWAKE) ||
  935. (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL))
  936. return;
  937. MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE);
  938. pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++;
  939. ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
  940. }
  941. void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
  942. u16 len, u32 sched_addr)
  943. {
  944. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  945. mci->gpm_addr = gpm_addr;
  946. mci->gpm_buf = gpm_buf;
  947. mci->gpm_len = len;
  948. mci->sched_addr = sched_addr;
  949. ar9003_mci_reset(ah, true, true, true);
  950. }
  951. EXPORT_SYMBOL(ar9003_mci_setup);
  952. void ar9003_mci_cleanup(struct ath_hw *ah)
  953. {
  954. /* Turn off MCI and Jupiter mode. */
  955. REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);
  956. ar9003_mci_disable_interrupt(ah);
  957. }
  958. EXPORT_SYMBOL(ar9003_mci_cleanup);
  959. u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
  960. {
  961. struct ath_common *common = ath9k_hw_common(ah);
  962. struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
  963. u32 value = 0, more_gpm = 0, gpm_ptr;
  964. u8 query_type;
  965. switch (state_type) {
  966. case MCI_STATE_ENABLE:
  967. if (mci->ready) {
  968. value = REG_READ(ah, AR_BTCOEX_CTRL);
  969. if ((value == 0xdeadbeef) || (value == 0xffffffff))
  970. value = 0;
  971. }
  972. value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
  973. break;
  974. case MCI_STATE_INIT_GPM_OFFSET:
  975. value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
  976. mci->gpm_idx = value;
  977. break;
  978. case MCI_STATE_NEXT_GPM_OFFSET:
  979. case MCI_STATE_LAST_GPM_OFFSET:
  980. /*
  981. * This could be useful to avoid new GPM message interrupt which
  982. * may lead to spurious interrupt after power sleep, or multiple
  983. * entry of ath_mci_intr().
  984. * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
  985. * alleviate this effect, but clearing GPM RX interrupt bit is
  986. * safe, because whether this is called from hw or driver code
  987. * there must be an interrupt bit set/triggered initially
  988. */
  989. REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
  990. AR_MCI_INTERRUPT_RX_MSG_GPM);
  991. gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
  992. value = gpm_ptr;
  993. if (value == 0)
  994. value = mci->gpm_len - 1;
  995. else if (value >= mci->gpm_len) {
  996. if (value != 0xFFFF)
  997. value = 0;
  998. } else {
  999. value--;
  1000. }
  1001. if (value == 0xFFFF) {
  1002. value = MCI_GPM_INVALID;
  1003. more_gpm = MCI_GPM_NOMORE;
  1004. } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) {
  1005. if (gpm_ptr == mci->gpm_idx) {
  1006. value = MCI_GPM_INVALID;
  1007. more_gpm = MCI_GPM_NOMORE;
  1008. } else {
  1009. for (;;) {
  1010. u32 temp_index;
  1011. /* skip reserved GPM if any */
  1012. if (value != mci->gpm_idx)
  1013. more_gpm = MCI_GPM_MORE;
  1014. else
  1015. more_gpm = MCI_GPM_NOMORE;
  1016. temp_index = mci->gpm_idx;
  1017. mci->gpm_idx++;
  1018. if (mci->gpm_idx >=
  1019. mci->gpm_len)
  1020. mci->gpm_idx = 0;
  1021. if (ar9003_mci_is_gpm_valid(ah,
  1022. temp_index)) {
  1023. value = temp_index;
  1024. break;
  1025. }
  1026. if (more_gpm == MCI_GPM_NOMORE) {
  1027. value = MCI_GPM_INVALID;
  1028. break;
  1029. }
  1030. }
  1031. }
  1032. if (p_data)
  1033. *p_data = more_gpm;
  1034. }
  1035. if (value != MCI_GPM_INVALID)
  1036. value <<= 4;
  1037. break;
  1038. case MCI_STATE_LAST_SCHD_MSG_OFFSET:
  1039. value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
  1040. AR_MCI_RX_LAST_SCHD_MSG_INDEX);
  1041. /* Make it in bytes */
  1042. value <<= 4;
  1043. break;
  1044. case MCI_STATE_REMOTE_SLEEP:
  1045. value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
  1046. AR_MCI_RX_REMOTE_SLEEP) ?
  1047. MCI_BT_SLEEP : MCI_BT_AWAKE;
  1048. break;
  1049. case MCI_STATE_CONT_RSSI_POWER:
  1050. value = MS(mci->cont_status, AR_MCI_CONT_RSSI_POWER);
  1051. break;
  1052. case MCI_STATE_CONT_PRIORITY:
  1053. value = MS(mci->cont_status, AR_MCI_CONT_RRIORITY);
  1054. break;
  1055. case MCI_STATE_CONT_TXRX:
  1056. value = MS(mci->cont_status, AR_MCI_CONT_TXRX);
  1057. break;
  1058. case MCI_STATE_BT:
  1059. value = mci->bt_state;
  1060. break;
  1061. case MCI_STATE_SET_BT_SLEEP:
  1062. mci->bt_state = MCI_BT_SLEEP;
  1063. break;
  1064. case MCI_STATE_SET_BT_AWAKE:
  1065. mci->bt_state = MCI_BT_AWAKE;
  1066. ar9003_mci_send_coex_version_query(ah, true);
  1067. ar9003_mci_send_coex_wlan_channels(ah, true);
  1068. if (mci->unhalt_bt_gpm)
  1069. ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
  1070. ar9003_mci_2g5g_switch(ah, true);
  1071. break;
  1072. case MCI_STATE_SET_BT_CAL_START:
  1073. mci->bt_state = MCI_BT_CAL_START;
  1074. break;
  1075. case MCI_STATE_SET_BT_CAL:
  1076. mci->bt_state = MCI_BT_CAL;
  1077. break;
  1078. case MCI_STATE_RESET_REQ_WAKE:
  1079. ar9003_mci_reset_req_wakeup(ah);
  1080. mci->update_2g5g = true;
  1081. if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MASK) {
  1082. /* Check if we still have control of the GPIOs */
  1083. if ((REG_READ(ah, AR_GLB_GPIO_CONTROL) &
  1084. ATH_MCI_CONFIG_MCI_OBS_GPIO) !=
  1085. ATH_MCI_CONFIG_MCI_OBS_GPIO) {
  1086. ar9003_mci_observation_set_up(ah);
  1087. }
  1088. }
  1089. break;
  1090. case MCI_STATE_SEND_WLAN_COEX_VERSION:
  1091. ar9003_mci_send_coex_version_response(ah, true);
  1092. break;
  1093. case MCI_STATE_SET_BT_COEX_VERSION:
  1094. if (!p_data)
  1095. ath_dbg(common, MCI,
  1096. "MCI Set BT Coex version with NULL data!!\n");
  1097. else {
  1098. mci->bt_ver_major = (*p_data >> 8) & 0xff;
  1099. mci->bt_ver_minor = (*p_data) & 0xff;
  1100. mci->bt_version_known = true;
  1101. ath_dbg(common, MCI, "MCI BT version set: %d.%d\n",
  1102. mci->bt_ver_major, mci->bt_ver_minor);
  1103. }
  1104. break;
  1105. case MCI_STATE_SEND_WLAN_CHANNELS:
  1106. if (p_data) {
  1107. if (((mci->wlan_channels[1] & 0xffff0000) ==
  1108. (*(p_data + 1) & 0xffff0000)) &&
  1109. (mci->wlan_channels[2] == *(p_data + 2)) &&
  1110. (mci->wlan_channels[3] == *(p_data + 3)))
  1111. break;
  1112. mci->wlan_channels[0] = *p_data++;
  1113. mci->wlan_channels[1] = *p_data++;
  1114. mci->wlan_channels[2] = *p_data++;
  1115. mci->wlan_channels[3] = *p_data++;
  1116. }
  1117. mci->wlan_channels_update = true;
  1118. ar9003_mci_send_coex_wlan_channels(ah, true);
  1119. break;
  1120. case MCI_STATE_SEND_VERSION_QUERY:
  1121. ar9003_mci_send_coex_version_query(ah, true);
  1122. break;
  1123. case MCI_STATE_SEND_STATUS_QUERY:
  1124. query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY;
  1125. ar9003_mci_send_coex_bt_status_query(ah, true, query_type);
  1126. break;
  1127. case MCI_STATE_NEED_FLUSH_BT_INFO:
  1128. /*
  1129. * btcoex_hw.mci.unhalt_bt_gpm means whether it's
  1130. * needed to send UNHALT message. It's set whenever
  1131. * there's a request to send HALT message.
  1132. * mci_halted_bt_gpm means whether HALT message is sent
  1133. * out successfully.
  1134. *
  1135. * Checking (mci_unhalt_bt_gpm == false) instead of
  1136. * checking (ah->mci_halted_bt_gpm == false) will make
  1137. * sure currently is in UNHALT-ed mode and BT can
  1138. * respond to status query.
  1139. */
  1140. value = (!mci->unhalt_bt_gpm &&
  1141. mci->need_flush_btinfo) ? 1 : 0;
  1142. if (p_data)
  1143. mci->need_flush_btinfo =
  1144. (*p_data != 0) ? true : false;
  1145. break;
  1146. case MCI_STATE_RECOVER_RX:
  1147. ar9003_mci_prep_interface(ah);
  1148. mci->query_bt = true;
  1149. mci->need_flush_btinfo = true;
  1150. ar9003_mci_send_coex_wlan_channels(ah, true);
  1151. ar9003_mci_2g5g_switch(ah, true);
  1152. break;
  1153. case MCI_STATE_NEED_FTP_STOMP:
  1154. value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP);
  1155. break;
  1156. case MCI_STATE_NEED_TUNING:
  1157. value = !(mci->config & ATH_MCI_CONFIG_DISABLE_TUNING);
  1158. break;
  1159. default:
  1160. break;
  1161. }
  1162. return value;
  1163. }
  1164. EXPORT_SYMBOL(ar9003_mci_state);