htc.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321
  1. // SPDX-License-Identifier: ISC
  2. /*
  3. * Copyright (c) 2005-2011 Atheros Communications Inc.
  4. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
  5. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  6. */
  7. #include "core.h"
  8. #include "hif.h"
  9. #include "debug.h"
  10. /********/
  11. /* Send */
  12. /********/
  13. static void ath10k_htc_control_tx_complete(struct ath10k *ar,
  14. struct sk_buff *skb)
  15. {
  16. kfree_skb(skb);
  17. }
  18. static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
  19. {
  20. struct sk_buff *skb;
  21. struct ath10k_skb_cb *skb_cb;
  22. skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE);
  23. if (!skb)
  24. return NULL;
  25. skb_reserve(skb, 20); /* FIXME: why 20 bytes? */
  26. WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
  27. skb_cb = ATH10K_SKB_CB(skb);
  28. memset(skb_cb, 0, sizeof(*skb_cb));
  29. ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %pK\n", __func__, skb);
  30. return skb;
  31. }
  32. static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
  33. struct sk_buff *skb)
  34. {
  35. struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
  36. if (htc->ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
  37. dma_unmap_single(htc->ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
  38. skb_pull(skb, sizeof(struct ath10k_htc_hdr));
  39. }
  40. void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
  41. struct sk_buff *skb)
  42. {
  43. struct ath10k *ar = ep->htc->ar;
  44. struct ath10k_htc_hdr *hdr;
  45. ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %pK\n", __func__,
  46. ep->eid, skb);
  47. /* A corner case where the copy completion is reaching to host but still
  48. * copy engine is processing it due to which host unmaps corresponding
  49. * memory and causes SMMU fault, hence as workaround adding delay
  50. * the unmapping memory to avoid SMMU faults.
  51. */
  52. if (ar->hw_params.delay_unmap_buffer &&
  53. ep->ul_pipe_id == 3)
  54. mdelay(2);
  55. hdr = (struct ath10k_htc_hdr *)skb->data;
  56. ath10k_htc_restore_tx_skb(ep->htc, skb);
  57. if (!ep->ep_ops.ep_tx_complete) {
  58. ath10k_warn(ar, "no tx handler for eid %d\n", ep->eid);
  59. dev_kfree_skb_any(skb);
  60. return;
  61. }
  62. if (hdr->flags & ATH10K_HTC_FLAG_SEND_BUNDLE) {
  63. dev_kfree_skb_any(skb);
  64. return;
  65. }
  66. ep->ep_ops.ep_tx_complete(ep->htc->ar, skb);
  67. }
  68. EXPORT_SYMBOL(ath10k_htc_notify_tx_completion);
  69. static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
  70. struct sk_buff *skb)
  71. {
  72. struct ath10k_htc_hdr *hdr;
  73. hdr = (struct ath10k_htc_hdr *)skb->data;
  74. memset(hdr, 0, sizeof(struct ath10k_htc_hdr));
  75. hdr->eid = ep->eid;
  76. hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
  77. hdr->flags = 0;
  78. if (ep->tx_credit_flow_enabled && !ep->bundle_tx)
  79. hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
  80. spin_lock_bh(&ep->htc->tx_lock);
  81. hdr->seq_no = ep->seq_no++;
  82. spin_unlock_bh(&ep->htc->tx_lock);
  83. }
  84. static int ath10k_htc_consume_credit(struct ath10k_htc_ep *ep,
  85. unsigned int len,
  86. bool consume)
  87. {
  88. struct ath10k_htc *htc = ep->htc;
  89. struct ath10k *ar = htc->ar;
  90. enum ath10k_htc_ep_id eid = ep->eid;
  91. int credits, ret = 0;
  92. if (!ep->tx_credit_flow_enabled)
  93. return 0;
  94. credits = DIV_ROUND_UP(len, ep->tx_credit_size);
  95. spin_lock_bh(&htc->tx_lock);
  96. if (ep->tx_credits < credits) {
  97. ath10k_dbg(ar, ATH10K_DBG_HTC,
  98. "htc insufficient credits ep %d required %d available %d consume %d\n",
  99. eid, credits, ep->tx_credits, consume);
  100. ret = -EAGAIN;
  101. goto unlock;
  102. }
  103. if (consume) {
  104. ep->tx_credits -= credits;
  105. ath10k_dbg(ar, ATH10K_DBG_HTC,
  106. "htc ep %d consumed %d credits total %d\n",
  107. eid, credits, ep->tx_credits);
  108. }
  109. unlock:
  110. spin_unlock_bh(&htc->tx_lock);
  111. return ret;
  112. }
  113. static void ath10k_htc_release_credit(struct ath10k_htc_ep *ep, unsigned int len)
  114. {
  115. struct ath10k_htc *htc = ep->htc;
  116. struct ath10k *ar = htc->ar;
  117. enum ath10k_htc_ep_id eid = ep->eid;
  118. int credits;
  119. if (!ep->tx_credit_flow_enabled)
  120. return;
  121. credits = DIV_ROUND_UP(len, ep->tx_credit_size);
  122. spin_lock_bh(&htc->tx_lock);
  123. ep->tx_credits += credits;
  124. ath10k_dbg(ar, ATH10K_DBG_HTC,
  125. "htc ep %d reverted %d credits back total %d\n",
  126. eid, credits, ep->tx_credits);
  127. spin_unlock_bh(&htc->tx_lock);
  128. if (ep->ep_ops.ep_tx_credits)
  129. ep->ep_ops.ep_tx_credits(htc->ar);
  130. }
  131. int ath10k_htc_send(struct ath10k_htc *htc,
  132. enum ath10k_htc_ep_id eid,
  133. struct sk_buff *skb)
  134. {
  135. struct ath10k *ar = htc->ar;
  136. struct ath10k_htc_ep *ep = &htc->endpoint[eid];
  137. struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
  138. struct ath10k_hif_sg_item sg_item;
  139. struct device *dev = htc->ar->dev;
  140. int ret;
  141. unsigned int skb_len;
  142. if (htc->ar->state == ATH10K_STATE_WEDGED)
  143. return -ECOMM;
  144. if (eid >= ATH10K_HTC_EP_COUNT) {
  145. ath10k_warn(ar, "Invalid endpoint id: %d\n", eid);
  146. return -ENOENT;
  147. }
  148. skb_push(skb, sizeof(struct ath10k_htc_hdr));
  149. skb_len = skb->len;
  150. ret = ath10k_htc_consume_credit(ep, skb_len, true);
  151. if (ret)
  152. goto err_pull;
  153. ath10k_htc_prepare_tx_skb(ep, skb);
  154. skb_cb->eid = eid;
  155. if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) {
  156. skb_cb->paddr = dma_map_single(dev, skb->data, skb->len,
  157. DMA_TO_DEVICE);
  158. ret = dma_mapping_error(dev, skb_cb->paddr);
  159. if (ret) {
  160. ret = -EIO;
  161. goto err_credits;
  162. }
  163. }
  164. sg_item.transfer_id = ep->eid;
  165. sg_item.transfer_context = skb;
  166. sg_item.vaddr = skb->data;
  167. sg_item.paddr = skb_cb->paddr;
  168. sg_item.len = skb->len;
  169. ret = ath10k_hif_tx_sg(htc->ar, ep->ul_pipe_id, &sg_item, 1);
  170. if (ret)
  171. goto err_unmap;
  172. return 0;
  173. err_unmap:
  174. if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
  175. dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
  176. err_credits:
  177. ath10k_htc_release_credit(ep, skb_len);
  178. err_pull:
  179. skb_pull(skb, sizeof(struct ath10k_htc_hdr));
  180. return ret;
  181. }
  182. void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
  183. {
  184. struct ath10k_htc *htc = &ar->htc;
  185. struct ath10k_skb_cb *skb_cb;
  186. struct ath10k_htc_ep *ep;
  187. if (WARN_ON_ONCE(!skb))
  188. return;
  189. skb_cb = ATH10K_SKB_CB(skb);
  190. ep = &htc->endpoint[skb_cb->eid];
  191. ath10k_htc_notify_tx_completion(ep, skb);
  192. /* the skb now belongs to the completion handler */
  193. }
  194. EXPORT_SYMBOL(ath10k_htc_tx_completion_handler);
  195. /***********/
  196. /* Receive */
  197. /***********/
  198. static void
  199. ath10k_htc_process_credit_report(struct ath10k_htc *htc,
  200. const struct ath10k_htc_credit_report *report,
  201. int len,
  202. enum ath10k_htc_ep_id eid)
  203. {
  204. struct ath10k *ar = htc->ar;
  205. struct ath10k_htc_ep *ep;
  206. int i, n_reports;
  207. if (len % sizeof(*report))
  208. ath10k_warn(ar, "Uneven credit report len %d", len);
  209. n_reports = len / sizeof(*report);
  210. spin_lock_bh(&htc->tx_lock);
  211. for (i = 0; i < n_reports; i++, report++) {
  212. if (report->eid >= ATH10K_HTC_EP_COUNT)
  213. break;
  214. ep = &htc->endpoint[report->eid];
  215. ep->tx_credits += report->credits;
  216. ath10k_dbg(ar, ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n",
  217. report->eid, report->credits, ep->tx_credits);
  218. if (ep->ep_ops.ep_tx_credits) {
  219. spin_unlock_bh(&htc->tx_lock);
  220. ep->ep_ops.ep_tx_credits(htc->ar);
  221. spin_lock_bh(&htc->tx_lock);
  222. }
  223. }
  224. spin_unlock_bh(&htc->tx_lock);
  225. }
  226. static int
  227. ath10k_htc_process_lookahead(struct ath10k_htc *htc,
  228. const struct ath10k_htc_lookahead_report *report,
  229. int len,
  230. enum ath10k_htc_ep_id eid,
  231. void *next_lookaheads,
  232. int *next_lookaheads_len)
  233. {
  234. struct ath10k *ar = htc->ar;
  235. /* Invalid lookahead flags are actually transmitted by
  236. * the target in the HTC control message.
  237. * Since this will happen at every boot we silently ignore
  238. * the lookahead in this case
  239. */
  240. if (report->pre_valid != ((~report->post_valid) & 0xFF))
  241. return 0;
  242. if (next_lookaheads && next_lookaheads_len) {
  243. ath10k_dbg(ar, ATH10K_DBG_HTC,
  244. "htc rx lookahead found pre_valid 0x%x post_valid 0x%x\n",
  245. report->pre_valid, report->post_valid);
  246. /* look ahead bytes are valid, copy them over */
  247. memcpy((u8 *)next_lookaheads, report->lookahead, 4);
  248. *next_lookaheads_len = 1;
  249. }
  250. return 0;
  251. }
  252. static int
  253. ath10k_htc_process_lookahead_bundle(struct ath10k_htc *htc,
  254. const struct ath10k_htc_lookahead_bundle *report,
  255. int len,
  256. enum ath10k_htc_ep_id eid,
  257. void *next_lookaheads,
  258. int *next_lookaheads_len)
  259. {
  260. struct ath10k *ar = htc->ar;
  261. int bundle_cnt = len / sizeof(*report);
  262. if (!bundle_cnt || (bundle_cnt > htc->max_msgs_per_htc_bundle)) {
  263. ath10k_warn(ar, "Invalid lookahead bundle count: %d\n",
  264. bundle_cnt);
  265. return -EINVAL;
  266. }
  267. if (next_lookaheads && next_lookaheads_len) {
  268. int i;
  269. for (i = 0; i < bundle_cnt; i++) {
  270. memcpy(((u8 *)next_lookaheads) + 4 * i,
  271. report->lookahead, 4);
  272. report++;
  273. }
  274. *next_lookaheads_len = bundle_cnt;
  275. }
  276. return 0;
  277. }
  278. int ath10k_htc_process_trailer(struct ath10k_htc *htc,
  279. u8 *buffer,
  280. int length,
  281. enum ath10k_htc_ep_id src_eid,
  282. void *next_lookaheads,
  283. int *next_lookaheads_len)
  284. {
  285. struct ath10k_htc_lookahead_bundle *bundle;
  286. struct ath10k *ar = htc->ar;
  287. int status = 0;
  288. struct ath10k_htc_record *record;
  289. u8 *orig_buffer;
  290. int orig_length;
  291. size_t len;
  292. orig_buffer = buffer;
  293. orig_length = length;
  294. while (length > 0) {
  295. record = (struct ath10k_htc_record *)buffer;
  296. if (length < sizeof(record->hdr)) {
  297. status = -EINVAL;
  298. break;
  299. }
  300. if (record->hdr.len > length) {
  301. /* no room left in buffer for record */
  302. ath10k_warn(ar, "Invalid record length: %d\n",
  303. record->hdr.len);
  304. status = -EINVAL;
  305. break;
  306. }
  307. switch (record->hdr.id) {
  308. case ATH10K_HTC_RECORD_CREDITS:
  309. len = sizeof(struct ath10k_htc_credit_report);
  310. if (record->hdr.len < len) {
  311. ath10k_warn(ar, "Credit report too long\n");
  312. status = -EINVAL;
  313. break;
  314. }
  315. ath10k_htc_process_credit_report(htc,
  316. record->credit_report,
  317. record->hdr.len,
  318. src_eid);
  319. break;
  320. case ATH10K_HTC_RECORD_LOOKAHEAD:
  321. len = sizeof(struct ath10k_htc_lookahead_report);
  322. if (record->hdr.len < len) {
  323. ath10k_warn(ar, "Lookahead report too long\n");
  324. status = -EINVAL;
  325. break;
  326. }
  327. status = ath10k_htc_process_lookahead(htc,
  328. record->lookahead_report,
  329. record->hdr.len,
  330. src_eid,
  331. next_lookaheads,
  332. next_lookaheads_len);
  333. break;
  334. case ATH10K_HTC_RECORD_LOOKAHEAD_BUNDLE:
  335. bundle = record->lookahead_bundle;
  336. status = ath10k_htc_process_lookahead_bundle(htc,
  337. bundle,
  338. record->hdr.len,
  339. src_eid,
  340. next_lookaheads,
  341. next_lookaheads_len);
  342. break;
  343. default:
  344. ath10k_warn(ar, "Unhandled record: id:%d length:%d\n",
  345. record->hdr.id, record->hdr.len);
  346. break;
  347. }
  348. if (status)
  349. break;
  350. /* multiple records may be present in a trailer */
  351. buffer += sizeof(record->hdr) + record->hdr.len;
  352. length -= sizeof(record->hdr) + record->hdr.len;
  353. }
  354. if (status)
  355. ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc rx bad trailer", "",
  356. orig_buffer, orig_length);
  357. return status;
  358. }
  359. EXPORT_SYMBOL(ath10k_htc_process_trailer);
  360. void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
  361. {
  362. int status = 0;
  363. struct ath10k_htc *htc = &ar->htc;
  364. struct ath10k_htc_hdr *hdr;
  365. struct ath10k_htc_ep *ep;
  366. u16 payload_len;
  367. u32 trailer_len = 0;
  368. size_t min_len;
  369. u8 eid;
  370. bool trailer_present;
  371. hdr = (struct ath10k_htc_hdr *)skb->data;
  372. skb_pull(skb, sizeof(*hdr));
  373. eid = hdr->eid;
  374. if (eid >= ATH10K_HTC_EP_COUNT) {
  375. ath10k_warn(ar, "HTC Rx: invalid eid %d\n", eid);
  376. ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad header", "",
  377. hdr, sizeof(*hdr));
  378. goto out;
  379. }
  380. ep = &htc->endpoint[eid];
  381. if (ep->service_id == ATH10K_HTC_SVC_ID_UNUSED) {
  382. ath10k_warn(ar, "htc rx endpoint %d is not connected\n", eid);
  383. goto out;
  384. }
  385. payload_len = __le16_to_cpu(hdr->len);
  386. if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) {
  387. ath10k_warn(ar, "HTC rx frame too long, len: %zu\n",
  388. payload_len + sizeof(*hdr));
  389. ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", "",
  390. hdr, sizeof(*hdr));
  391. goto out;
  392. }
  393. if (skb->len < payload_len) {
  394. ath10k_dbg(ar, ATH10K_DBG_HTC,
  395. "HTC Rx: insufficient length, got %d, expected %d\n",
  396. skb->len, payload_len);
  397. ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len",
  398. "", hdr, sizeof(*hdr));
  399. goto out;
  400. }
  401. /* get flags to check for trailer */
  402. trailer_present = hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
  403. if (trailer_present) {
  404. u8 *trailer;
  405. trailer_len = hdr->trailer_len;
  406. min_len = sizeof(struct ath10k_ath10k_htc_record_hdr);
  407. if ((trailer_len < min_len) ||
  408. (trailer_len > payload_len)) {
  409. ath10k_warn(ar, "Invalid trailer length: %d\n",
  410. trailer_len);
  411. goto out;
  412. }
  413. trailer = (u8 *)hdr;
  414. trailer += sizeof(*hdr);
  415. trailer += payload_len;
  416. trailer -= trailer_len;
  417. status = ath10k_htc_process_trailer(htc, trailer,
  418. trailer_len, hdr->eid,
  419. NULL, NULL);
  420. if (status)
  421. goto out;
  422. skb_trim(skb, skb->len - trailer_len);
  423. }
  424. if (((int)payload_len - (int)trailer_len) <= 0)
  425. /* zero length packet with trailer data, just drop these */
  426. goto out;
  427. ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %pK\n",
  428. eid, skb);
  429. ep->ep_ops.ep_rx_complete(ar, skb);
  430. /* skb is now owned by the rx completion handler */
  431. skb = NULL;
  432. out:
  433. kfree_skb(skb);
  434. }
  435. EXPORT_SYMBOL(ath10k_htc_rx_completion_handler);
  436. static void ath10k_htc_control_rx_complete(struct ath10k *ar,
  437. struct sk_buff *skb)
  438. {
  439. struct ath10k_htc *htc = &ar->htc;
  440. struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data;
  441. switch (__le16_to_cpu(msg->hdr.message_id)) {
  442. case ATH10K_HTC_MSG_READY_ID:
  443. case ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID:
  444. /* handle HTC control message */
  445. if (completion_done(&htc->ctl_resp)) {
  446. /* this is a fatal error, target should not be
  447. * sending unsolicited messages on the ep 0
  448. */
  449. ath10k_warn(ar, "HTC rx ctrl still processing\n");
  450. complete(&htc->ctl_resp);
  451. goto out;
  452. }
  453. htc->control_resp_len =
  454. min_t(int, skb->len,
  455. ATH10K_HTC_MAX_CTRL_MSG_LEN);
  456. memcpy(htc->control_resp_buffer, skb->data,
  457. htc->control_resp_len);
  458. complete(&htc->ctl_resp);
  459. break;
  460. case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE:
  461. htc->htc_ops.target_send_suspend_complete(ar);
  462. break;
  463. default:
  464. ath10k_warn(ar, "ignoring unsolicited htc ep0 event\n");
  465. break;
  466. }
  467. out:
  468. kfree_skb(skb);
  469. }
  470. /***************/
  471. /* Init/Deinit */
  472. /***************/
  473. static const char *htc_service_name(enum ath10k_htc_svc_id id)
  474. {
  475. switch (id) {
  476. case ATH10K_HTC_SVC_ID_RESERVED:
  477. return "Reserved";
  478. case ATH10K_HTC_SVC_ID_RSVD_CTRL:
  479. return "Control";
  480. case ATH10K_HTC_SVC_ID_WMI_CONTROL:
  481. return "WMI";
  482. case ATH10K_HTC_SVC_ID_WMI_DATA_BE:
  483. return "DATA BE";
  484. case ATH10K_HTC_SVC_ID_WMI_DATA_BK:
  485. return "DATA BK";
  486. case ATH10K_HTC_SVC_ID_WMI_DATA_VI:
  487. return "DATA VI";
  488. case ATH10K_HTC_SVC_ID_WMI_DATA_VO:
  489. return "DATA VO";
  490. case ATH10K_HTC_SVC_ID_NMI_CONTROL:
  491. return "NMI Control";
  492. case ATH10K_HTC_SVC_ID_NMI_DATA:
  493. return "NMI Data";
  494. case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:
  495. return "HTT Data";
  496. case ATH10K_HTC_SVC_ID_HTT_DATA2_MSG:
  497. return "HTT Data";
  498. case ATH10K_HTC_SVC_ID_HTT_DATA3_MSG:
  499. return "HTT Data";
  500. case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS:
  501. return "RAW";
  502. case ATH10K_HTC_SVC_ID_HTT_LOG_MSG:
  503. return "PKTLOG";
  504. }
  505. return "Unknown";
  506. }
  507. static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc)
  508. {
  509. struct ath10k_htc_ep *ep;
  510. int i;
  511. for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) {
  512. ep = &htc->endpoint[i];
  513. ep->service_id = ATH10K_HTC_SVC_ID_UNUSED;
  514. ep->max_ep_message_len = 0;
  515. ep->max_tx_queue_depth = 0;
  516. ep->eid = i;
  517. ep->htc = htc;
  518. ep->tx_credit_flow_enabled = true;
  519. }
  520. }
  521. static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
  522. u16 service_id)
  523. {
  524. u8 allocation = 0;
  525. /* The WMI control service is the only service with flow control.
  526. * Let it have all transmit credits.
  527. */
  528. if (service_id == ATH10K_HTC_SVC_ID_WMI_CONTROL)
  529. allocation = htc->total_transmit_credits;
  530. return allocation;
  531. }
  532. static int ath10k_htc_send_bundle(struct ath10k_htc_ep *ep,
  533. struct sk_buff *bundle_skb,
  534. struct sk_buff_head *tx_save_head)
  535. {
  536. struct ath10k_hif_sg_item sg_item;
  537. struct ath10k_htc *htc = ep->htc;
  538. struct ath10k *ar = htc->ar;
  539. struct sk_buff *skb;
  540. int ret, cn = 0;
  541. unsigned int skb_len;
  542. ath10k_dbg(ar, ATH10K_DBG_HTC, "bundle skb len %d\n", bundle_skb->len);
  543. skb_len = bundle_skb->len;
  544. ret = ath10k_htc_consume_credit(ep, skb_len, true);
  545. if (!ret) {
  546. sg_item.transfer_id = ep->eid;
  547. sg_item.transfer_context = bundle_skb;
  548. sg_item.vaddr = bundle_skb->data;
  549. sg_item.len = bundle_skb->len;
  550. ret = ath10k_hif_tx_sg(htc->ar, ep->ul_pipe_id, &sg_item, 1);
  551. if (ret)
  552. ath10k_htc_release_credit(ep, skb_len);
  553. }
  554. if (ret)
  555. dev_kfree_skb_any(bundle_skb);
  556. for (cn = 0; (skb = skb_dequeue_tail(tx_save_head)); cn++) {
  557. if (ret) {
  558. skb_pull(skb, sizeof(struct ath10k_htc_hdr));
  559. skb_queue_head(&ep->tx_req_head, skb);
  560. } else {
  561. skb_queue_tail(&ep->tx_complete_head, skb);
  562. }
  563. }
  564. if (!ret)
  565. queue_work(ar->workqueue_tx_complete, &ar->tx_complete_work);
  566. ath10k_dbg(ar, ATH10K_DBG_HTC,
  567. "bundle tx status %d eid %d req count %d count %d len %d\n",
  568. ret, ep->eid, skb_queue_len(&ep->tx_req_head), cn, skb_len);
  569. return ret;
  570. }
  571. static void ath10k_htc_send_one_skb(struct ath10k_htc_ep *ep, struct sk_buff *skb)
  572. {
  573. struct ath10k_htc *htc = ep->htc;
  574. struct ath10k *ar = htc->ar;
  575. int ret;
  576. ret = ath10k_htc_send(htc, ep->eid, skb);
  577. if (ret)
  578. skb_queue_head(&ep->tx_req_head, skb);
  579. ath10k_dbg(ar, ATH10K_DBG_HTC, "tx one status %d eid %d len %d pending count %d\n",
  580. ret, ep->eid, skb->len, skb_queue_len(&ep->tx_req_head));
  581. }
  582. static int ath10k_htc_send_bundle_skbs(struct ath10k_htc_ep *ep)
  583. {
  584. struct ath10k_htc *htc = ep->htc;
  585. struct sk_buff *bundle_skb, *skb;
  586. struct sk_buff_head tx_save_head;
  587. struct ath10k_htc_hdr *hdr;
  588. u8 *bundle_buf;
  589. int ret = 0, credit_pad, credit_remainder, trans_len, bundles_left = 0;
  590. if (htc->ar->state == ATH10K_STATE_WEDGED)
  591. return -ECOMM;
  592. if (ep->tx_credit_flow_enabled &&
  593. ep->tx_credits < ATH10K_MIN_CREDIT_PER_HTC_TX_BUNDLE)
  594. return 0;
  595. bundles_left = ATH10K_MAX_MSG_PER_HTC_TX_BUNDLE * ep->tx_credit_size;
  596. bundle_skb = dev_alloc_skb(bundles_left);
  597. if (!bundle_skb)
  598. return -ENOMEM;
  599. bundle_buf = bundle_skb->data;
  600. skb_queue_head_init(&tx_save_head);
  601. while (true) {
  602. skb = skb_dequeue(&ep->tx_req_head);
  603. if (!skb)
  604. break;
  605. credit_pad = 0;
  606. trans_len = skb->len + sizeof(*hdr);
  607. credit_remainder = trans_len % ep->tx_credit_size;
  608. if (credit_remainder != 0) {
  609. credit_pad = ep->tx_credit_size - credit_remainder;
  610. trans_len += credit_pad;
  611. }
  612. ret = ath10k_htc_consume_credit(ep,
  613. bundle_buf + trans_len - bundle_skb->data,
  614. false);
  615. if (ret) {
  616. skb_queue_head(&ep->tx_req_head, skb);
  617. break;
  618. }
  619. if (bundles_left < trans_len) {
  620. bundle_skb->len = bundle_buf - bundle_skb->data;
  621. ret = ath10k_htc_send_bundle(ep, bundle_skb, &tx_save_head);
  622. if (ret) {
  623. skb_queue_head(&ep->tx_req_head, skb);
  624. return ret;
  625. }
  626. if (skb_queue_len(&ep->tx_req_head) == 0) {
  627. ath10k_htc_send_one_skb(ep, skb);
  628. return ret;
  629. }
  630. if (ep->tx_credit_flow_enabled &&
  631. ep->tx_credits < ATH10K_MIN_CREDIT_PER_HTC_TX_BUNDLE) {
  632. skb_queue_head(&ep->tx_req_head, skb);
  633. return 0;
  634. }
  635. bundles_left =
  636. ATH10K_MAX_MSG_PER_HTC_TX_BUNDLE * ep->tx_credit_size;
  637. bundle_skb = dev_alloc_skb(bundles_left);
  638. if (!bundle_skb) {
  639. skb_queue_head(&ep->tx_req_head, skb);
  640. return -ENOMEM;
  641. }
  642. bundle_buf = bundle_skb->data;
  643. skb_queue_head_init(&tx_save_head);
  644. }
  645. skb_push(skb, sizeof(struct ath10k_htc_hdr));
  646. ath10k_htc_prepare_tx_skb(ep, skb);
  647. memcpy(bundle_buf, skb->data, skb->len);
  648. hdr = (struct ath10k_htc_hdr *)bundle_buf;
  649. hdr->flags |= ATH10K_HTC_FLAG_SEND_BUNDLE;
  650. hdr->pad_len = __cpu_to_le16(credit_pad);
  651. bundle_buf += trans_len;
  652. bundles_left -= trans_len;
  653. skb_queue_tail(&tx_save_head, skb);
  654. }
  655. if (bundle_buf != bundle_skb->data) {
  656. bundle_skb->len = bundle_buf - bundle_skb->data;
  657. ret = ath10k_htc_send_bundle(ep, bundle_skb, &tx_save_head);
  658. } else {
  659. dev_kfree_skb_any(bundle_skb);
  660. }
  661. return ret;
  662. }
  663. static void ath10k_htc_bundle_tx_work(struct work_struct *work)
  664. {
  665. struct ath10k *ar = container_of(work, struct ath10k, bundle_tx_work);
  666. struct ath10k_htc_ep *ep;
  667. struct sk_buff *skb;
  668. int i;
  669. for (i = 0; i < ARRAY_SIZE(ar->htc.endpoint); i++) {
  670. ep = &ar->htc.endpoint[i];
  671. if (!ep->bundle_tx)
  672. continue;
  673. ath10k_dbg(ar, ATH10K_DBG_HTC, "bundle tx work eid %d count %d\n",
  674. ep->eid, skb_queue_len(&ep->tx_req_head));
  675. if (skb_queue_len(&ep->tx_req_head) >=
  676. ATH10K_MIN_MSG_PER_HTC_TX_BUNDLE) {
  677. ath10k_htc_send_bundle_skbs(ep);
  678. } else {
  679. skb = skb_dequeue(&ep->tx_req_head);
  680. if (!skb)
  681. continue;
  682. ath10k_htc_send_one_skb(ep, skb);
  683. }
  684. }
  685. }
  686. static void ath10k_htc_tx_complete_work(struct work_struct *work)
  687. {
  688. struct ath10k *ar = container_of(work, struct ath10k, tx_complete_work);
  689. struct ath10k_htc_ep *ep;
  690. enum ath10k_htc_ep_id eid;
  691. struct sk_buff *skb;
  692. int i;
  693. for (i = 0; i < ARRAY_SIZE(ar->htc.endpoint); i++) {
  694. ep = &ar->htc.endpoint[i];
  695. eid = ep->eid;
  696. if (ep->bundle_tx && eid == ar->htt.eid) {
  697. ath10k_dbg(ar, ATH10K_DBG_HTC, "bundle tx complete eid %d pending complete count%d\n",
  698. ep->eid, skb_queue_len(&ep->tx_complete_head));
  699. while (true) {
  700. skb = skb_dequeue(&ep->tx_complete_head);
  701. if (!skb)
  702. break;
  703. ath10k_htc_notify_tx_completion(ep, skb);
  704. }
  705. }
  706. }
  707. }
  708. int ath10k_htc_send_hl(struct ath10k_htc *htc,
  709. enum ath10k_htc_ep_id eid,
  710. struct sk_buff *skb)
  711. {
  712. struct ath10k_htc_ep *ep = &htc->endpoint[eid];
  713. struct ath10k *ar = htc->ar;
  714. if (sizeof(struct ath10k_htc_hdr) + skb->len > ep->tx_credit_size) {
  715. ath10k_dbg(ar, ATH10K_DBG_HTC, "tx exceed max len %d\n", skb->len);
  716. return -ENOMEM;
  717. }
  718. ath10k_dbg(ar, ATH10K_DBG_HTC, "htc send hl eid %d bundle %d tx count %d len %d\n",
  719. eid, ep->bundle_tx, skb_queue_len(&ep->tx_req_head), skb->len);
  720. if (ep->bundle_tx) {
  721. skb_queue_tail(&ep->tx_req_head, skb);
  722. queue_work(ar->workqueue, &ar->bundle_tx_work);
  723. return 0;
  724. } else {
  725. return ath10k_htc_send(htc, eid, skb);
  726. }
  727. }
  728. void ath10k_htc_setup_tx_req(struct ath10k_htc_ep *ep)
  729. {
  730. if (ep->htc->max_msgs_per_htc_bundle >= ATH10K_MIN_MSG_PER_HTC_TX_BUNDLE &&
  731. !ep->bundle_tx) {
  732. ep->bundle_tx = true;
  733. skb_queue_head_init(&ep->tx_req_head);
  734. skb_queue_head_init(&ep->tx_complete_head);
  735. }
  736. }
  737. void ath10k_htc_stop_hl(struct ath10k *ar)
  738. {
  739. struct ath10k_htc_ep *ep;
  740. int i;
  741. cancel_work_sync(&ar->bundle_tx_work);
  742. cancel_work_sync(&ar->tx_complete_work);
  743. for (i = 0; i < ARRAY_SIZE(ar->htc.endpoint); i++) {
  744. ep = &ar->htc.endpoint[i];
  745. if (!ep->bundle_tx)
  746. continue;
  747. ath10k_dbg(ar, ATH10K_DBG_HTC, "stop tx work eid %d count %d\n",
  748. ep->eid, skb_queue_len(&ep->tx_req_head));
  749. skb_queue_purge(&ep->tx_req_head);
  750. }
  751. }
  752. int ath10k_htc_wait_target(struct ath10k_htc *htc)
  753. {
  754. struct ath10k *ar = htc->ar;
  755. int i, status = 0;
  756. unsigned long time_left;
  757. struct ath10k_htc_msg *msg;
  758. u16 message_id;
  759. time_left = wait_for_completion_timeout(&htc->ctl_resp,
  760. ATH10K_HTC_WAIT_TIMEOUT_HZ);
  761. if (!time_left) {
  762. /* Workaround: In some cases the PCI HIF doesn't
  763. * receive interrupt for the control response message
  764. * even if the buffer was completed. It is suspected
  765. * iomap writes unmasking PCI CE irqs aren't propagated
  766. * properly in KVM PCI-passthrough sometimes.
  767. */
  768. ath10k_warn(ar, "failed to receive control response completion, polling..\n");
  769. for (i = 0; i < CE_COUNT; i++)
  770. ath10k_hif_send_complete_check(htc->ar, i, 1);
  771. time_left =
  772. wait_for_completion_timeout(&htc->ctl_resp,
  773. ATH10K_HTC_WAIT_TIMEOUT_HZ);
  774. if (!time_left)
  775. status = -ETIMEDOUT;
  776. }
  777. if (status < 0) {
  778. ath10k_err(ar, "ctl_resp never came in (%d)\n", status);
  779. return status;
  780. }
  781. if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) {
  782. ath10k_err(ar, "Invalid HTC ready msg len:%d\n",
  783. htc->control_resp_len);
  784. return -ECOMM;
  785. }
  786. msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
  787. message_id = __le16_to_cpu(msg->hdr.message_id);
  788. if (message_id != ATH10K_HTC_MSG_READY_ID) {
  789. ath10k_err(ar, "Invalid HTC ready msg: 0x%x\n", message_id);
  790. return -ECOMM;
  791. }
  792. if (ar->hw_params.use_fw_tx_credits)
  793. htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
  794. else
  795. htc->total_transmit_credits = 1;
  796. htc->target_credit_size = __le16_to_cpu(msg->ready.credit_size);
  797. ath10k_dbg(ar, ATH10K_DBG_HTC,
  798. "Target ready! transmit resources: %d size:%d actual credits:%d\n",
  799. htc->total_transmit_credits,
  800. htc->target_credit_size,
  801. msg->ready.credit_count);
  802. if ((htc->total_transmit_credits == 0) ||
  803. (htc->target_credit_size == 0)) {
  804. ath10k_err(ar, "Invalid credit size received\n");
  805. return -ECOMM;
  806. }
  807. /* The only way to determine if the ready message is an extended
  808. * message is from the size.
  809. */
  810. if (htc->control_resp_len >=
  811. sizeof(msg->hdr) + sizeof(msg->ready_ext)) {
  812. htc->alt_data_credit_size =
  813. __le16_to_cpu(msg->ready_ext.reserved) &
  814. ATH10K_HTC_MSG_READY_EXT_ALT_DATA_MASK;
  815. htc->max_msgs_per_htc_bundle =
  816. min_t(u8, msg->ready_ext.max_msgs_per_htc_bundle,
  817. HTC_HOST_MAX_MSG_PER_RX_BUNDLE);
  818. ath10k_dbg(ar, ATH10K_DBG_HTC,
  819. "Extended ready message RX bundle size %d alt size %d\n",
  820. htc->max_msgs_per_htc_bundle,
  821. htc->alt_data_credit_size);
  822. }
  823. INIT_WORK(&ar->bundle_tx_work, ath10k_htc_bundle_tx_work);
  824. INIT_WORK(&ar->tx_complete_work, ath10k_htc_tx_complete_work);
  825. return 0;
  826. }
  827. void ath10k_htc_change_tx_credit_flow(struct ath10k_htc *htc,
  828. enum ath10k_htc_ep_id eid,
  829. bool enable)
  830. {
  831. struct ath10k *ar = htc->ar;
  832. struct ath10k_htc_ep *ep = &ar->htc.endpoint[eid];
  833. ep->tx_credit_flow_enabled = enable;
  834. }
  835. int ath10k_htc_connect_service(struct ath10k_htc *htc,
  836. struct ath10k_htc_svc_conn_req *conn_req,
  837. struct ath10k_htc_svc_conn_resp *conn_resp)
  838. {
  839. struct ath10k *ar = htc->ar;
  840. struct ath10k_htc_msg *msg;
  841. struct ath10k_htc_conn_svc *req_msg;
  842. struct ath10k_htc_conn_svc_response resp_msg_dummy;
  843. struct ath10k_htc_conn_svc_response *resp_msg = &resp_msg_dummy;
  844. enum ath10k_htc_ep_id assigned_eid = ATH10K_HTC_EP_COUNT;
  845. struct ath10k_htc_ep *ep;
  846. struct sk_buff *skb;
  847. unsigned int max_msg_size = 0;
  848. int length, status;
  849. unsigned long time_left;
  850. bool disable_credit_flow_ctrl = false;
  851. u16 message_id, service_id, flags = 0;
  852. u8 tx_alloc = 0;
  853. /* special case for HTC pseudo control service */
  854. if (conn_req->service_id == ATH10K_HTC_SVC_ID_RSVD_CTRL) {
  855. disable_credit_flow_ctrl = true;
  856. assigned_eid = ATH10K_HTC_EP_0;
  857. max_msg_size = ATH10K_HTC_MAX_CTRL_MSG_LEN;
  858. memset(&resp_msg_dummy, 0, sizeof(resp_msg_dummy));
  859. goto setup;
  860. }
  861. tx_alloc = ath10k_htc_get_credit_allocation(htc,
  862. conn_req->service_id);
  863. if (!tx_alloc)
  864. ath10k_dbg(ar, ATH10K_DBG_BOOT,
  865. "boot htc service %s does not allocate target credits\n",
  866. htc_service_name(conn_req->service_id));
  867. skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
  868. if (!skb) {
  869. ath10k_err(ar, "Failed to allocate HTC packet\n");
  870. return -ENOMEM;
  871. }
  872. length = sizeof(msg->hdr) + sizeof(msg->connect_service);
  873. skb_put(skb, length);
  874. memset(skb->data, 0, length);
  875. msg = (struct ath10k_htc_msg *)skb->data;
  876. msg->hdr.message_id =
  877. __cpu_to_le16(ATH10K_HTC_MSG_CONNECT_SERVICE_ID);
  878. flags |= SM(tx_alloc, ATH10K_HTC_CONN_FLAGS_RECV_ALLOC);
  879. /* Only enable credit flow control for WMI ctrl service */
  880. if (conn_req->service_id != ATH10K_HTC_SVC_ID_WMI_CONTROL) {
  881. flags |= ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
  882. disable_credit_flow_ctrl = true;
  883. }
  884. req_msg = &msg->connect_service;
  885. req_msg->flags = __cpu_to_le16(flags);
  886. req_msg->service_id = __cpu_to_le16(conn_req->service_id);
  887. reinit_completion(&htc->ctl_resp);
  888. status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
  889. if (status) {
  890. kfree_skb(skb);
  891. return status;
  892. }
  893. /* wait for response */
  894. time_left = wait_for_completion_timeout(&htc->ctl_resp,
  895. ATH10K_HTC_CONN_SVC_TIMEOUT_HZ);
  896. if (!time_left) {
  897. ath10k_err(ar, "Service connect timeout\n");
  898. return -ETIMEDOUT;
  899. }
  900. /* we controlled the buffer creation, it's aligned */
  901. msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
  902. resp_msg = &msg->connect_service_response;
  903. message_id = __le16_to_cpu(msg->hdr.message_id);
  904. service_id = __le16_to_cpu(resp_msg->service_id);
  905. if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) ||
  906. (htc->control_resp_len < sizeof(msg->hdr) +
  907. sizeof(msg->connect_service_response))) {
  908. ath10k_err(ar, "Invalid resp message ID 0x%x", message_id);
  909. return -EPROTO;
  910. }
  911. ath10k_dbg(ar, ATH10K_DBG_HTC,
  912. "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n",
  913. htc_service_name(service_id),
  914. resp_msg->status, resp_msg->eid);
  915. conn_resp->connect_resp_code = resp_msg->status;
  916. /* check response status */
  917. if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) {
  918. ath10k_err(ar, "HTC Service %s connect request failed: 0x%x)\n",
  919. htc_service_name(service_id),
  920. resp_msg->status);
  921. return -EPROTO;
  922. }
  923. assigned_eid = (enum ath10k_htc_ep_id)resp_msg->eid;
  924. max_msg_size = __le16_to_cpu(resp_msg->max_msg_size);
  925. setup:
  926. if (assigned_eid >= ATH10K_HTC_EP_COUNT)
  927. return -EPROTO;
  928. if (max_msg_size == 0)
  929. return -EPROTO;
  930. ep = &htc->endpoint[assigned_eid];
  931. ep->eid = assigned_eid;
  932. if (ep->service_id != ATH10K_HTC_SVC_ID_UNUSED)
  933. return -EPROTO;
  934. /* return assigned endpoint to caller */
  935. conn_resp->eid = assigned_eid;
  936. conn_resp->max_msg_len = __le16_to_cpu(resp_msg->max_msg_size);
  937. /* setup the endpoint */
  938. ep->service_id = conn_req->service_id;
  939. ep->max_tx_queue_depth = conn_req->max_send_queue_depth;
  940. ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size);
  941. ep->tx_credits = tx_alloc;
  942. ep->tx_credit_size = htc->target_credit_size;
  943. if (conn_req->service_id == ATH10K_HTC_SVC_ID_HTT_DATA_MSG &&
  944. htc->alt_data_credit_size != 0)
  945. ep->tx_credit_size = htc->alt_data_credit_size;
  946. /* copy all the callbacks */
  947. ep->ep_ops = conn_req->ep_ops;
  948. status = ath10k_hif_map_service_to_pipe(htc->ar,
  949. ep->service_id,
  950. &ep->ul_pipe_id,
  951. &ep->dl_pipe_id);
  952. if (status) {
  953. ath10k_dbg(ar, ATH10K_DBG_BOOT, "unsupported HTC service id: %d\n",
  954. ep->service_id);
  955. return status;
  956. }
  957. ath10k_dbg(ar, ATH10K_DBG_BOOT,
  958. "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n",
  959. htc_service_name(ep->service_id), ep->ul_pipe_id,
  960. ep->dl_pipe_id, ep->eid);
  961. if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) {
  962. ep->tx_credit_flow_enabled = false;
  963. ath10k_dbg(ar, ATH10K_DBG_BOOT,
  964. "boot htc service '%s' eid %d TX flow control disabled\n",
  965. htc_service_name(ep->service_id), assigned_eid);
  966. }
  967. return status;
  968. }
  969. struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size)
  970. {
  971. struct sk_buff *skb;
  972. skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr));
  973. if (!skb)
  974. return NULL;
  975. skb_reserve(skb, sizeof(struct ath10k_htc_hdr));
  976. /* FW/HTC requires 4-byte aligned streams */
  977. if (!IS_ALIGNED((unsigned long)skb->data, 4))
  978. ath10k_warn(ar, "Unaligned HTC tx skb\n");
  979. return skb;
  980. }
  981. static void ath10k_htc_pktlog_process_rx(struct ath10k *ar, struct sk_buff *skb)
  982. {
  983. trace_ath10k_htt_pktlog(ar, skb->data, skb->len);
  984. dev_kfree_skb_any(skb);
  985. }
  986. static int ath10k_htc_pktlog_connect(struct ath10k *ar)
  987. {
  988. struct ath10k_htc_svc_conn_resp conn_resp;
  989. struct ath10k_htc_svc_conn_req conn_req;
  990. int status;
  991. memset(&conn_req, 0, sizeof(conn_req));
  992. memset(&conn_resp, 0, sizeof(conn_resp));
  993. conn_req.ep_ops.ep_tx_complete = NULL;
  994. conn_req.ep_ops.ep_rx_complete = ath10k_htc_pktlog_process_rx;
  995. conn_req.ep_ops.ep_tx_credits = NULL;
  996. /* connect to control service */
  997. conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_LOG_MSG;
  998. status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp);
  999. if (status) {
  1000. ath10k_warn(ar, "failed to connect to PKTLOG service: %d\n",
  1001. status);
  1002. return status;
  1003. }
  1004. return 0;
  1005. }
  1006. static bool ath10k_htc_pktlog_svc_supported(struct ath10k *ar)
  1007. {
  1008. u8 ul_pipe_id;
  1009. u8 dl_pipe_id;
  1010. int status;
  1011. status = ath10k_hif_map_service_to_pipe(ar, ATH10K_HTC_SVC_ID_HTT_LOG_MSG,
  1012. &ul_pipe_id,
  1013. &dl_pipe_id);
  1014. if (status) {
  1015. ath10k_dbg(ar, ATH10K_DBG_BOOT, "unsupported HTC pktlog service id: %d\n",
  1016. ATH10K_HTC_SVC_ID_HTT_LOG_MSG);
  1017. return false;
  1018. }
  1019. return true;
  1020. }
  1021. int ath10k_htc_start(struct ath10k_htc *htc)
  1022. {
  1023. struct ath10k *ar = htc->ar;
  1024. struct sk_buff *skb;
  1025. int status = 0;
  1026. struct ath10k_htc_msg *msg;
  1027. skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
  1028. if (!skb)
  1029. return -ENOMEM;
  1030. skb_put(skb, sizeof(msg->hdr) + sizeof(msg->setup_complete_ext));
  1031. memset(skb->data, 0, skb->len);
  1032. msg = (struct ath10k_htc_msg *)skb->data;
  1033. msg->hdr.message_id =
  1034. __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID);
  1035. if (ar->hif.bus == ATH10K_BUS_SDIO) {
  1036. /* Extra setup params used by SDIO */
  1037. msg->setup_complete_ext.flags =
  1038. __cpu_to_le32(ATH10K_HTC_SETUP_COMPLETE_FLAGS_RX_BNDL_EN);
  1039. msg->setup_complete_ext.max_msgs_per_bundled_recv =
  1040. htc->max_msgs_per_htc_bundle;
  1041. }
  1042. ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC is using TX credit flow control\n");
  1043. status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
  1044. if (status) {
  1045. kfree_skb(skb);
  1046. return status;
  1047. }
  1048. if (ath10k_htc_pktlog_svc_supported(ar)) {
  1049. status = ath10k_htc_pktlog_connect(ar);
  1050. if (status) {
  1051. ath10k_err(ar, "failed to connect to pktlog: %d\n", status);
  1052. return status;
  1053. }
  1054. }
  1055. return 0;
  1056. }
  1057. /* registered target arrival callback from the HIF layer */
  1058. int ath10k_htc_init(struct ath10k *ar)
  1059. {
  1060. int status;
  1061. struct ath10k_htc *htc = &ar->htc;
  1062. struct ath10k_htc_svc_conn_req conn_req;
  1063. struct ath10k_htc_svc_conn_resp conn_resp;
  1064. spin_lock_init(&htc->tx_lock);
  1065. ath10k_htc_reset_endpoint_states(htc);
  1066. htc->ar = ar;
  1067. /* setup our pseudo HTC control endpoint connection */
  1068. memset(&conn_req, 0, sizeof(conn_req));
  1069. memset(&conn_resp, 0, sizeof(conn_resp));
  1070. conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete;
  1071. conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete;
  1072. conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS;
  1073. conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL;
  1074. /* connect fake service */
  1075. status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
  1076. if (status) {
  1077. ath10k_err(ar, "could not connect to htc service (%d)\n",
  1078. status);
  1079. return status;
  1080. }
  1081. init_completion(&htc->ctl_resp);
  1082. return 0;
  1083. }