usbdrv.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267
  1. /*
  2. * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  3. *
  4. * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  5. *
  6. *
  7. * Permission to use, copy, modify, and/or distribute this software for
  8. * any purpose with or without fee is hereby granted, provided that the
  9. * above copyright notice and this permission notice appear in all
  10. * copies.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  13. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  14. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  15. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  16. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  17. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  18. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  19. * PERFORMANCE OF THIS SOFTWARE.
  20. */
  21. /*
  22. * This file was originally distributed by Qualcomm Atheros, Inc.
  23. * under proprietary terms before Copyright ownership was assigned
  24. * to the Linux Foundation.
  25. */
  26. #define ATH_MODULE_NAME hif
  27. #include "a_debug.h"
  28. #include "hif_usb_internal.h"
  29. #include "if_usb.h"
  30. #include "cds_api.h"
  31. #include "hif_debug.h"
  32. #define IS_BULK_EP(attr) (((attr) & 3) == 0x02)
  33. #define IS_INT_EP(attr) (((attr) & 3) == 0x03)
  34. #define IS_ISOC_EP(attr) (((attr) & 3) == 0x01)
  35. #define IS_DIR_IN(addr) ((addr) & 0x80)
  36. #define IS_FW_CRASH_DUMP(x)(((x == FW_ASSERT_PATTERN) || \
  37. (x == FW_REG_PATTERN) || \
  38. ((x & FW_RAMDUMP_PATTERN_MASK) == \
  39. FW_RAMDUMP_PATTERN)) ? 1 : 0)
  40. static void usb_hif_post_recv_transfers(HIF_USB_PIPE *recv_pipe,
  41. int buffer_length);
  42. static void usb_hif_post_recv_bundle_transfers
  43. (HIF_USB_PIPE *recv_pipe,
  44. int buffer_length);
  45. static void usb_hif_cleanup_recv_urb(HIF_URB_CONTEXT *urb_context);
  46. /**
  47. * usb_hif_free_urb_to_pipe() - add urb back to urb list of a pipe
  48. * @pipe: pointer to HIF_USB_PIPE
  49. * @urb_context: pointer to HIF_URB_CONTEXT
  50. *
  51. * Return: none
  52. */
  53. static void usb_hif_free_urb_to_pipe(HIF_USB_PIPE *pipe,
  54. HIF_URB_CONTEXT *urb_context)
  55. {
  56. qdf_spin_lock_irqsave(&pipe->device->cs_lock);
  57. pipe->urb_cnt++;
  58. DL_ListAdd(&pipe->urb_list_head, &urb_context->link);
  59. qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
  60. }
  61. /**
  62. * usb_hif_alloc_urb_from_pipe() - remove urb back from urb list of a pipe
  63. * @pipe: pointer to HIF_USB_PIPE
  64. *
  65. * Return: HIF_URB_CONTEXT urb context removed from the urb list
  66. */
  67. HIF_URB_CONTEXT *usb_hif_alloc_urb_from_pipe(HIF_USB_PIPE *pipe)
  68. {
  69. HIF_URB_CONTEXT *urb_context = NULL;
  70. DL_LIST *item;
  71. qdf_spin_lock_irqsave(&pipe->device->cs_lock);
  72. item = dl_list_remove_item_from_head(&pipe->urb_list_head);
  73. if (item != NULL) {
  74. urb_context = A_CONTAINING_STRUCT(item, HIF_URB_CONTEXT, link);
  75. pipe->urb_cnt--;
  76. }
  77. qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
  78. return urb_context;
  79. }
  80. /**
  81. * usb_hif_dequeue_pending_transfer() - remove urb from pending xfer list
  82. * @pipe: pointer to HIF_USB_PIPE
  83. *
  84. * Return: HIF_URB_CONTEXT urb context removed from the pending xfer list
  85. */
  86. static HIF_URB_CONTEXT *usb_hif_dequeue_pending_transfer
  87. (HIF_USB_PIPE *pipe)
  88. {
  89. HIF_URB_CONTEXT *urb_context = NULL;
  90. DL_LIST *item;
  91. qdf_spin_lock_irqsave(&pipe->device->cs_lock);
  92. item = dl_list_remove_item_from_head(&pipe->urb_pending_list);
  93. if (item != NULL)
  94. urb_context = A_CONTAINING_STRUCT(item, HIF_URB_CONTEXT, link);
  95. qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
  96. return urb_context;
  97. }
  98. /**
  99. * usb_hif_enqueue_pending_transfer() - add urb to pending xfer list
  100. * @pipe: pointer to HIF_USB_PIPE
  101. * @urb_context: pointer to HIF_URB_CONTEXT to be added to the xfer list
  102. *
  103. * Return: none
  104. */
  105. void usb_hif_enqueue_pending_transfer(HIF_USB_PIPE *pipe,
  106. HIF_URB_CONTEXT *urb_context)
  107. {
  108. qdf_spin_lock_irqsave(&pipe->device->cs_lock);
  109. dl_list_insert_tail(&pipe->urb_pending_list, &urb_context->link);
  110. qdf_spin_unlock_irqrestore(&pipe->device->cs_lock);
  111. }
  112. /**
  113. * usb_hif_remove_pending_transfer() - remove urb from its own list
  114. * @urb_context: pointer to HIF_URB_CONTEXT to be removed
  115. *
  116. * Return: none
  117. */
  118. void
  119. usb_hif_remove_pending_transfer(HIF_URB_CONTEXT *urb_context)
  120. {
  121. qdf_spin_lock_irqsave(&urb_context->pipe->device->cs_lock);
  122. dl_list_remove(&urb_context->link);
  123. qdf_spin_unlock_irqrestore(&urb_context->pipe->device->cs_lock);
  124. }
  125. /**
  126. * usb_hif_alloc_pipe_resources() - allocate urb_cnt urbs to a HIF pipe
  127. * @pipe: pointer to HIF_USB_PIPE to which resources will be allocated
  128. * @urb_cnt: number of urbs to be added to the HIF pipe
  129. *
  130. * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
  131. */
  132. static QDF_STATUS usb_hif_alloc_pipe_resources
  133. (HIF_USB_PIPE *pipe, int urb_cnt)
  134. {
  135. QDF_STATUS status = QDF_STATUS_SUCCESS;
  136. int i;
  137. HIF_URB_CONTEXT *urb_context;
  138. DL_LIST_INIT(&pipe->urb_list_head);
  139. DL_LIST_INIT(&pipe->urb_pending_list);
  140. for (i = 0; i < urb_cnt; i++) {
  141. urb_context = qdf_mem_malloc(sizeof(*urb_context));
  142. if (NULL == urb_context) {
  143. status = QDF_STATUS_E_NOMEM;
  144. HIF_ERROR("urb_context is null");
  145. break;
  146. }
  147. urb_context->pipe = pipe;
  148. urb_context->urb = usb_alloc_urb(0, GFP_KERNEL);
  149. if (NULL == urb_context->urb) {
  150. status = QDF_STATUS_E_NOMEM;
  151. qdf_mem_free(urb_context);
  152. HIF_ERROR("urb_context->urb is null");
  153. break;
  154. }
  155. /* note we are only allocate the urb contexts here, the actual
  156. * URB is
  157. * allocated from the kernel as needed to do a transaction
  158. */
  159. pipe->urb_alloc++;
  160. usb_hif_free_urb_to_pipe(pipe, urb_context);
  161. }
  162. HIF_DBG("athusb: alloc resources lpipe:%d hpipe:0x%X urbs:%d",
  163. pipe->logical_pipe_num,
  164. pipe->usb_pipe_handle,
  165. pipe->urb_alloc);
  166. return status;
  167. }
  168. /**
  169. * usb_hif_free_pipe_resources() - free urb resources allocated to a HIF pipe
  170. * @pipe: pointer to HIF_USB_PIPE
  171. *
  172. * Return: none
  173. */
  174. static void usb_hif_free_pipe_resources(HIF_USB_PIPE *pipe)
  175. {
  176. HIF_URB_CONTEXT *urb_context;
  177. if (NULL == pipe->device) {
  178. /* nothing allocated for this pipe */
  179. HIF_ERROR("pipe->device is null");
  180. return;
  181. }
  182. HIF_TRACE("athusb: free resources lpipe:%d hpipe:0x%X urbs:%d avail:%d",
  183. pipe->logical_pipe_num,
  184. pipe->usb_pipe_handle, pipe->urb_alloc,
  185. pipe->urb_cnt);
  186. if (pipe->urb_alloc != pipe->urb_cnt) {
  187. HIF_ERROR("athusb: urb leak! lpipe:%d hpipe:0x%X urbs:%d avail:%d",
  188. pipe->logical_pipe_num,
  189. pipe->usb_pipe_handle, pipe->urb_alloc,
  190. pipe->urb_cnt);
  191. }
  192. while (true) {
  193. urb_context = usb_hif_alloc_urb_from_pipe(pipe);
  194. if (NULL == urb_context)
  195. break;
  196. if (urb_context->buf) {
  197. qdf_nbuf_free(urb_context->buf);
  198. urb_context->buf = NULL;
  199. }
  200. usb_free_urb(urb_context->urb);
  201. urb_context->urb = NULL;
  202. qdf_mem_free(urb_context);
  203. }
  204. }
  205. /**
  206. * usb_hif_get_logical_pipe_num() - get pipe number for a particular enpoint
  207. * @device: pointer to HIF_DEVICE_USB structure
  208. * @ep_address: endpoint address
  209. * @urb_count: number of urb resources to be allocated to the pipe
  210. *
  211. * Return: uint8_t pipe number corresponding to ep_address
  212. */
  213. static uint8_t usb_hif_get_logical_pipe_num
  214. (HIF_DEVICE_USB *device,
  215. uint8_t ep_address,
  216. int *urb_count)
  217. {
  218. uint8_t pipe_num = HIF_USB_PIPE_INVALID;
  219. switch (ep_address) {
  220. case USB_EP_ADDR_APP_CTRL_IN:
  221. pipe_num = HIF_RX_CTRL_PIPE;
  222. *urb_count = RX_URB_COUNT;
  223. break;
  224. case USB_EP_ADDR_APP_DATA_IN:
  225. pipe_num = HIF_RX_DATA_PIPE;
  226. *urb_count = RX_URB_COUNT;
  227. break;
  228. case USB_EP_ADDR_APP_INT_IN:
  229. pipe_num = HIF_RX_INT_PIPE;
  230. *urb_count = RX_URB_COUNT;
  231. break;
  232. case USB_EP_ADDR_APP_DATA2_IN:
  233. pipe_num = HIF_RX_DATA2_PIPE;
  234. *urb_count = RX_URB_COUNT;
  235. break;
  236. case USB_EP_ADDR_APP_CTRL_OUT:
  237. pipe_num = HIF_TX_CTRL_PIPE;
  238. *urb_count = TX_URB_COUNT;
  239. break;
  240. case USB_EP_ADDR_APP_DATA_LP_OUT:
  241. pipe_num = HIF_TX_DATA_LP_PIPE;
  242. *urb_count = TX_URB_COUNT;
  243. break;
  244. case USB_EP_ADDR_APP_DATA_MP_OUT:
  245. pipe_num = HIF_TX_DATA_MP_PIPE;
  246. *urb_count = TX_URB_COUNT;
  247. break;
  248. case USB_EP_ADDR_APP_DATA_HP_OUT:
  249. pipe_num = HIF_TX_DATA_HP_PIPE;
  250. *urb_count = TX_URB_COUNT;
  251. break;
  252. default:
  253. /* note: there may be endpoints not currently used */
  254. break;
  255. }
  256. return pipe_num;
  257. }
  258. /**
  259. * usb_hif_get_logical_pipe_num() - setup urb resources for all pipes
  260. * @device: pointer to HIF_DEVICE_USB structure
  261. *
  262. * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
  263. */
  264. QDF_STATUS usb_hif_setup_pipe_resources(HIF_DEVICE_USB *device)
  265. {
  266. struct usb_interface *interface = device->interface;
  267. struct usb_host_interface *iface_desc = interface->cur_altsetting;
  268. struct usb_endpoint_descriptor *endpoint;
  269. int i;
  270. int urbcount;
  271. QDF_STATUS status = QDF_STATUS_SUCCESS;
  272. HIF_USB_PIPE *pipe;
  273. uint8_t pipe_num;
  274. /* walk decriptors and setup pipes */
  275. for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
  276. endpoint = &iface_desc->endpoint[i].desc;
  277. if (IS_BULK_EP(endpoint->bmAttributes)) {
  278. HIF_DBG("%s Bulk Ep:0x%2.2X " "maxpktsz:%d",
  279. IS_DIR_IN(endpoint->bEndpointAddress) ?
  280. "RX" : "TX",
  281. endpoint->bEndpointAddress,
  282. qdf_le16_to_cpu(endpoint->wMaxPacketSize));
  283. } else if (IS_INT_EP(endpoint->bmAttributes)) {
  284. HIF_DBG("%s Int Ep:0x%2.2X maxpktsz:%d interval:%d",
  285. IS_DIR_IN(endpoint->bEndpointAddress) ?
  286. "RX" : "TX",
  287. endpoint->bEndpointAddress,
  288. qdf_le16_to_cpu(endpoint->wMaxPacketSize),
  289. endpoint->bInterval);
  290. } else if (IS_ISOC_EP(endpoint->bmAttributes)) {
  291. /* TODO for ISO */
  292. HIF_DBG("%s ISOC Ep:0x%2.2X maxpktsz:%d interval:%d",
  293. IS_DIR_IN(endpoint->bEndpointAddress) ?
  294. "RX" : "TX",
  295. endpoint->bEndpointAddress,
  296. qdf_le16_to_cpu(endpoint->wMaxPacketSize),
  297. endpoint->bInterval);
  298. }
  299. urbcount = 0;
  300. pipe_num = usb_hif_get_logical_pipe_num(device,
  301. endpoint->bEndpointAddress,
  302. &urbcount);
  303. if (HIF_USB_PIPE_INVALID == pipe_num)
  304. continue;
  305. pipe = &device->pipes[pipe_num];
  306. if (pipe->device != NULL) {
  307. /*pipe was already setup */
  308. continue;
  309. }
  310. pipe->device = device;
  311. pipe->logical_pipe_num = pipe_num;
  312. pipe->ep_address = endpoint->bEndpointAddress;
  313. pipe->max_packet_size =
  314. qdf_le16_to_cpu(endpoint->wMaxPacketSize);
  315. if (IS_BULK_EP(endpoint->bmAttributes)) {
  316. if (IS_DIR_IN(pipe->ep_address)) {
  317. pipe->usb_pipe_handle =
  318. usb_rcvbulkpipe(device->udev,
  319. pipe->ep_address);
  320. } else {
  321. pipe->usb_pipe_handle =
  322. usb_sndbulkpipe(device->udev,
  323. pipe->ep_address);
  324. }
  325. } else if (IS_INT_EP(endpoint->bmAttributes)) {
  326. if (IS_DIR_IN(pipe->ep_address)) {
  327. pipe->usb_pipe_handle =
  328. usb_rcvintpipe(device->udev,
  329. pipe->ep_address);
  330. } else {
  331. pipe->usb_pipe_handle =
  332. usb_sndintpipe(device->udev,
  333. pipe->ep_address);
  334. }
  335. } else if (IS_ISOC_EP(endpoint->bmAttributes)) {
  336. /* TODO for ISO */
  337. if (IS_DIR_IN(pipe->ep_address)) {
  338. pipe->usb_pipe_handle =
  339. usb_rcvisocpipe(device->udev,
  340. pipe->ep_address);
  341. } else {
  342. pipe->usb_pipe_handle =
  343. usb_sndisocpipe(device->udev,
  344. pipe->ep_address);
  345. }
  346. }
  347. pipe->ep_desc = endpoint;
  348. if (!IS_DIR_IN(pipe->ep_address))
  349. pipe->flags |= HIF_USB_PIPE_FLAG_TX;
  350. status = usb_hif_alloc_pipe_resources(pipe, urbcount);
  351. if (!QDF_IS_STATUS_SUCCESS(status))
  352. break;
  353. }
  354. return status;
  355. }
  356. /**
  357. * usb_hif_cleanup_pipe_resources() - free urb resources for all pipes
  358. * @device: pointer to HIF_DEVICE_USB structure
  359. *
  360. * Return: none
  361. */
  362. void usb_hif_cleanup_pipe_resources(HIF_DEVICE_USB *device)
  363. {
  364. int i;
  365. for (i = 0; i < HIF_USB_PIPE_MAX; i++)
  366. usb_hif_free_pipe_resources(&device->pipes[i]);
  367. }
  368. /**
  369. * usb_hif_flush_pending_transfers() - kill pending urbs for a pipe
  370. * @pipe: pointer to HIF_USB_PIPE structure
  371. *
  372. * Return: none
  373. */
  374. static void usb_hif_flush_pending_transfers(HIF_USB_PIPE *pipe)
  375. {
  376. HIF_URB_CONTEXT *urb_context;
  377. HIF_TRACE("+%s pipe : %d", __func__, pipe->logical_pipe_num);
  378. while (1) {
  379. urb_context = usb_hif_dequeue_pending_transfer(pipe);
  380. if (NULL == urb_context) {
  381. HIF_WARN("urb_context is NULL");
  382. break;
  383. }
  384. HIF_TRACE(" pending urb ctxt: 0x%p", urb_context);
  385. if (urb_context->urb != NULL) {
  386. HIF_TRACE(" killing urb: 0x%p", urb_context->urb);
  387. /* killing the URB will cause the completion routines to
  388. * run
  389. */
  390. usb_kill_urb(urb_context->urb);
  391. }
  392. }
  393. HIF_TRACE("-%s", __func__);
  394. }
  395. /**
  396. * usb_hif_flush_all() - flush pending transfers for all pipes for a usb bus
  397. * @device: pointer to HIF_DEVICE_USB structure
  398. *
  399. * Return: none
  400. */
  401. void usb_hif_flush_all(HIF_DEVICE_USB *device)
  402. {
  403. int i;
  404. HIF_USB_PIPE *pipe;
  405. HIF_TRACE("+%s", __func__);
  406. for (i = 0; i < HIF_USB_PIPE_MAX; i++) {
  407. if (device->pipes[i].device != NULL) {
  408. usb_hif_flush_pending_transfers(&device->pipes[i]);
  409. pipe = &device->pipes[i];
  410. HIF_USB_FLUSH_WORK(pipe);
  411. }
  412. }
  413. HIF_TRACE("-%s", __func__);
  414. }
  415. /**
  416. * usb_hif_cleanup_recv_urb() - cleanup recv urb
  417. * @urb_context: pointer to HIF_URB_CONTEXT structure
  418. *
  419. * Return: none
  420. */
  421. static void usb_hif_cleanup_recv_urb(HIF_URB_CONTEXT *urb_context)
  422. {
  423. HIF_TRACE("+%s", __func__);
  424. if (urb_context->buf != NULL) {
  425. qdf_nbuf_free(urb_context->buf);
  426. urb_context->buf = NULL;
  427. }
  428. usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
  429. HIF_TRACE("-%s", __func__);
  430. }
  431. /**
  432. * usb_hif_cleanup_transmit_urb() - cleanup transmit urb
  433. * @urb_context: pointer to HIF_URB_CONTEXT structure
  434. *
  435. * Return: none
  436. */
  437. void usb_hif_cleanup_transmit_urb(HIF_URB_CONTEXT *urb_context)
  438. {
  439. usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
  440. }
  441. /**
  442. * usb_hif_usb_recv_prestart_complete() - completion routine for prestart rx urb
  443. * @urb: urb for which the completion routine is being called
  444. *
  445. * Return: none
  446. */
  447. static void usb_hif_usb_recv_prestart_complete
  448. (struct urb *urb)
  449. {
  450. HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context;
  451. QDF_STATUS status = QDF_STATUS_SUCCESS;
  452. qdf_nbuf_t buf = NULL;
  453. HIF_USB_PIPE *pipe = urb_context->pipe;
  454. HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p",
  455. __func__,
  456. pipe->logical_pipe_num,
  457. urb->status, urb->actual_length,
  458. urb);
  459. /* this urb is not pending anymore */
  460. usb_hif_remove_pending_transfer(urb_context);
  461. do {
  462. if (urb->status != 0) {
  463. status = A_ECOMM;
  464. switch (urb->status) {
  465. case -ECONNRESET:
  466. case -ENOENT:
  467. case -ESHUTDOWN:
  468. /* NOTE: no need to spew these errors when
  469. * device is removed
  470. * or urb is killed due to driver shutdown
  471. */
  472. status = A_ECANCELED;
  473. break;
  474. default:
  475. HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
  476. __func__,
  477. pipe->logical_pipe_num,
  478. pipe->ep_address,
  479. urb->status);
  480. break;
  481. }
  482. break;
  483. }
  484. if (urb->actual_length == 0)
  485. break;
  486. buf = urb_context->buf;
  487. /* we are going to pass it up */
  488. urb_context->buf = NULL;
  489. qdf_nbuf_put_tail(buf, urb->actual_length);
  490. if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
  491. uint8_t *data;
  492. uint32_t len;
  493. qdf_nbuf_peek_header(buf, &data, &len);
  494. debug_dump_bytes(data, len, "hif recv data");
  495. }
  496. /* note: queue implements a lock */
  497. skb_queue_tail(&pipe->io_comp_queue, buf);
  498. HIF_USB_SCHEDULE_WORK(pipe);
  499. } while (false);
  500. usb_hif_cleanup_recv_urb(urb_context);
  501. /* Prestart URBs runs out and now start working receive pipe. */
  502. if (--pipe->urb_prestart_cnt == 0)
  503. usb_hif_start_recv_pipes(pipe->device);
  504. HIF_DBG("-%s", __func__);
  505. }
  506. /**
  507. * usb_hif_usb_recv_complete() - completion routine for rx urb
  508. * @urb: urb for which the completion routine is being called
  509. *
  510. * Return: none
  511. */
  512. static void usb_hif_usb_recv_complete(struct urb *urb)
  513. {
  514. HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context;
  515. QDF_STATUS status = QDF_STATUS_SUCCESS;
  516. qdf_nbuf_t buf = NULL;
  517. HIF_USB_PIPE *pipe = urb_context->pipe;
  518. struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
  519. HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p",
  520. __func__,
  521. pipe->logical_pipe_num,
  522. urb->status, urb->actual_length,
  523. urb);
  524. /* this urb is not pending anymore */
  525. usb_hif_remove_pending_transfer(urb_context);
  526. do {
  527. if (urb->status != 0) {
  528. status = A_ECOMM;
  529. switch (urb->status) {
  530. #ifdef RX_SG_SUPPORT
  531. case -EOVERFLOW:
  532. urb->actual_length = HIF_USB_RX_BUFFER_SIZE;
  533. status = QDF_STATUS_SUCCESS;
  534. break;
  535. #endif
  536. case -ECONNRESET:
  537. case -ENOENT:
  538. case -ESHUTDOWN:
  539. /* NOTE: no need to spew these errors when
  540. * device is removed
  541. * or urb is killed due to driver shutdown
  542. */
  543. status = A_ECANCELED;
  544. break;
  545. default:
  546. HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
  547. __func__,
  548. pipe->logical_pipe_num,
  549. pipe->ep_address,
  550. urb->status);
  551. break;
  552. }
  553. break;
  554. }
  555. if (urb->actual_length == 0)
  556. break;
  557. buf = urb_context->buf;
  558. /* we are going to pass it up */
  559. urb_context->buf = NULL;
  560. qdf_nbuf_put_tail(buf, urb->actual_length);
  561. if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
  562. uint8_t *data;
  563. uint32_t len;
  564. qdf_nbuf_peek_header(buf, &data, &len);
  565. debug_dump_bytes(data, len, "hif recv data");
  566. }
  567. /* note: queue implements a lock */
  568. skb_queue_tail(&pipe->io_comp_queue, buf);
  569. HIF_USB_SCHEDULE_WORK(pipe);
  570. } while (false);
  571. usb_hif_cleanup_recv_urb(urb_context);
  572. /* Only re-submit URB when STATUS is success and HIF is not at the
  573. suspend state.
  574. */
  575. if (QDF_IS_STATUS_SUCCESS(status) && !sc->suspend_state) {
  576. if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
  577. /* our free urbs are piling up, post more transfers */
  578. usb_hif_post_recv_transfers(pipe,
  579. HIF_USB_RX_BUFFER_SIZE);
  580. }
  581. } else {
  582. HIF_ERROR("%s: pipe: %d, fail to post URB: status(%d) suspend (%d)",
  583. __func__,
  584. pipe->logical_pipe_num,
  585. urb->status,
  586. sc->suspend_state);
  587. }
  588. HIF_DBG("-%s", __func__);
  589. }
  590. /**
  591. * usb_hif_usb_recv_bundle_complete() - completion routine for rx bundling urb
  592. * @urb: urb for which the completion routine is being called
  593. *
  594. * Return: none
  595. */
  596. static void usb_hif_usb_recv_bundle_complete(struct urb *urb)
  597. {
  598. HIF_URB_CONTEXT *urb_context = (HIF_URB_CONTEXT *) urb->context;
  599. QDF_STATUS status = QDF_STATUS_SUCCESS;
  600. qdf_nbuf_t buf = NULL;
  601. HIF_USB_PIPE *pipe = urb_context->pipe;
  602. uint8_t *netdata, *netdata_new;
  603. uint32_t netlen, netlen_new;
  604. HTC_FRAME_HDR *HtcHdr;
  605. uint16_t payloadLen;
  606. qdf_nbuf_t new_skb = NULL;
  607. HIF_DBG("+%s: recv pipe: %d, stat:%d,len:%d urb:0x%p",
  608. __func__,
  609. pipe->logical_pipe_num,
  610. urb->status, urb->actual_length,
  611. urb);
  612. /* this urb is not pending anymore */
  613. usb_hif_remove_pending_transfer(urb_context);
  614. do {
  615. if (urb->status != 0) {
  616. status = A_ECOMM;
  617. switch (urb->status) {
  618. case -ECONNRESET:
  619. case -ENOENT:
  620. case -ESHUTDOWN:
  621. /* NOTE: no need to spew these errors when
  622. * device is removed
  623. * or urb is killed due to driver shutdown
  624. */
  625. status = A_ECANCELED;
  626. break;
  627. default:
  628. HIF_ERROR("%s recv pipe: %d (ep:0x%2.2X), failed:%d",
  629. __func__,
  630. pipe->logical_pipe_num,
  631. pipe->ep_address,
  632. urb->status);
  633. break;
  634. }
  635. break;
  636. }
  637. if (urb->actual_length == 0)
  638. break;
  639. buf = urb_context->buf;
  640. if (AR_DEBUG_LVL_CHECK(USB_HIF_DEBUG_DUMP_DATA)) {
  641. uint8_t *data;
  642. uint32_t len;
  643. qdf_nbuf_peek_header(buf, &data, &len);
  644. debug_dump_bytes(data, len, "hif recv data");
  645. }
  646. qdf_nbuf_peek_header(buf, &netdata, &netlen);
  647. netlen = urb->actual_length;
  648. do {
  649. uint16_t frame_len;
  650. if (IS_FW_CRASH_DUMP(*(uint32_t *) netdata))
  651. frame_len = netlen;
  652. else {
  653. /* Hack into HTC header for bundle processing */
  654. HtcHdr = (HTC_FRAME_HDR *) netdata;
  655. if (HtcHdr->EndpointID >= ENDPOINT_MAX) {
  656. HIF_ERROR("athusb: Rx: invalid EndpointID=%d",
  657. HtcHdr->EndpointID);
  658. break;
  659. }
  660. payloadLen = HtcHdr->PayloadLen;
  661. payloadLen = qdf_le16_to_cpu(payloadLen);
  662. if (payloadLen > HIF_USB_RX_BUFFER_SIZE) {
  663. HIF_ERROR("athusb: payloadLen too long %u",
  664. payloadLen);
  665. break;
  666. }
  667. frame_len = (HTC_HDR_LENGTH + payloadLen);
  668. }
  669. if (netlen < frame_len) {
  670. HIF_ERROR("athusb: subframe length %d not fitted into bundle packet length %d"
  671. , netlen, frame_len);
  672. break;
  673. }
  674. /* allocate a new skb and copy */
  675. new_skb =
  676. qdf_nbuf_alloc(NULL, frame_len, 0, 4, false);
  677. if (new_skb == NULL) {
  678. HIF_ERROR("athusb: allocate skb (len=%u) failed"
  679. , frame_len);
  680. break;
  681. }
  682. qdf_nbuf_peek_header(new_skb, &netdata_new,
  683. &netlen_new);
  684. qdf_mem_copy(netdata_new, netdata, frame_len);
  685. qdf_nbuf_put_tail(new_skb, frame_len);
  686. skb_queue_tail(&pipe->io_comp_queue, new_skb);
  687. new_skb = NULL;
  688. netdata += frame_len;
  689. netlen -= frame_len;
  690. } while (netlen);
  691. HIF_USB_SCHEDULE_WORK(pipe);
  692. } while (false);
  693. if (urb_context->buf == NULL)
  694. HIF_ERROR("athusb: buffer in urb_context is NULL");
  695. /* reset urb_context->buf ==> seems not necessary */
  696. usb_hif_free_urb_to_pipe(urb_context->pipe, urb_context);
  697. if (QDF_IS_STATUS_SUCCESS(status)) {
  698. if (pipe->urb_cnt >= pipe->urb_cnt_thresh) {
  699. /* our free urbs are piling up, post more transfers */
  700. usb_hif_post_recv_bundle_transfers(pipe,
  701. pipe->device->rx_bundle_buf_len);
  702. }
  703. }
  704. HIF_DBG("-%s", __func__);
  705. }
  706. /**
  707. * usb_hif_post_recv_prestart_transfers() - post prestart recv urbs for a pipe
  708. * @recv_pipe: rx data pipe
  709. * @prestart_urb: number of prestart recv urbs to be posted
  710. *
  711. * Return: none
  712. */
  713. static void usb_hif_post_recv_prestart_transfers
  714. (HIF_USB_PIPE *recv_pipe,
  715. int prestart_urb)
  716. {
  717. HIF_URB_CONTEXT *urb_context;
  718. uint8_t *data;
  719. uint32_t len;
  720. struct urb *urb;
  721. int i, usb_status, buffer_length = HIF_USB_RX_BUFFER_SIZE;
  722. HIF_TRACE("+%s", __func__);
  723. for (i = 0; i < prestart_urb; i++) {
  724. urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
  725. if (NULL == urb_context)
  726. break;
  727. urb_context->buf =
  728. qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false);
  729. if (NULL == urb_context->buf) {
  730. usb_hif_cleanup_recv_urb(urb_context);
  731. break;
  732. }
  733. qdf_nbuf_peek_header(urb_context->buf, &data, &len);
  734. urb = urb_context->urb;
  735. usb_fill_bulk_urb(urb,
  736. recv_pipe->device->udev,
  737. recv_pipe->usb_pipe_handle,
  738. data,
  739. buffer_length,
  740. usb_hif_usb_recv_prestart_complete,
  741. urb_context);
  742. HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%p",
  743. recv_pipe->logical_pipe_num,
  744. recv_pipe->usb_pipe_handle,
  745. recv_pipe->ep_address, buffer_length,
  746. urb_context->buf);
  747. usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
  748. usb_status = usb_submit_urb(urb, GFP_ATOMIC);
  749. if (usb_status) {
  750. HIF_ERROR("athusb : usb bulk recv failed %d",
  751. usb_status);
  752. usb_hif_remove_pending_transfer(urb_context);
  753. usb_hif_cleanup_recv_urb(urb_context);
  754. break;
  755. } else
  756. recv_pipe->urb_prestart_cnt++;
  757. }
  758. HIF_TRACE("-%s", __func__);
  759. }
  760. /**
  761. * usb_hif_post_recv_transfers() - post recv urbs for a given pipe
  762. * @recv_pipe: recv pipe for which urbs need to be posted
  763. * @buffer_length: buffer length of the recv urbs
  764. *
  765. * Return: none
  766. */
  767. static void usb_hif_post_recv_transfers(HIF_USB_PIPE *recv_pipe,
  768. int buffer_length)
  769. {
  770. HIF_URB_CONTEXT *urb_context;
  771. uint8_t *data;
  772. uint32_t len;
  773. struct urb *urb;
  774. int usb_status;
  775. HIF_TRACE("+%s", __func__);
  776. while (1) {
  777. urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
  778. if (NULL == urb_context)
  779. break;
  780. urb_context->buf = qdf_nbuf_alloc(NULL, buffer_length, 0,
  781. 4, false);
  782. if (NULL == urb_context->buf) {
  783. usb_hif_cleanup_recv_urb(urb_context);
  784. break;
  785. }
  786. qdf_nbuf_peek_header(urb_context->buf, &data, &len);
  787. urb = urb_context->urb;
  788. usb_fill_bulk_urb(urb,
  789. recv_pipe->device->udev,
  790. recv_pipe->usb_pipe_handle,
  791. data,
  792. buffer_length,
  793. usb_hif_usb_recv_complete, urb_context);
  794. HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%p",
  795. recv_pipe->logical_pipe_num,
  796. recv_pipe->usb_pipe_handle,
  797. recv_pipe->ep_address, buffer_length,
  798. urb_context->buf);
  799. usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
  800. usb_status = usb_submit_urb(urb, GFP_ATOMIC);
  801. if (usb_status) {
  802. HIF_ERROR("athusb : usb bulk recv failed %d",
  803. usb_status);
  804. usb_hif_remove_pending_transfer(urb_context);
  805. usb_hif_cleanup_recv_urb(urb_context);
  806. break;
  807. }
  808. }
  809. HIF_TRACE("-%s", __func__);
  810. }
  811. /**
  812. * usb_hif_post_recv_bundle_transfers() - post recv urbs for a given pipe
  813. * @recv_pipe: recv pipe for which urbs need to be posted
  814. * @buffer_length: maximum length of rx bundle
  815. *
  816. * Return: none
  817. */
  818. static void usb_hif_post_recv_bundle_transfers
  819. (HIF_USB_PIPE *recv_pipe,
  820. int buffer_length)
  821. {
  822. HIF_URB_CONTEXT *urb_context;
  823. uint8_t *data;
  824. uint32_t len;
  825. struct urb *urb;
  826. int usb_status;
  827. HIF_TRACE("+%s", __func__);
  828. while (1) {
  829. urb_context = usb_hif_alloc_urb_from_pipe(recv_pipe);
  830. if (NULL == urb_context)
  831. break;
  832. if (NULL == urb_context->buf) {
  833. urb_context->buf =
  834. qdf_nbuf_alloc(NULL, buffer_length, 0, 4, false);
  835. if (NULL == urb_context->buf) {
  836. usb_hif_cleanup_recv_urb(urb_context);
  837. break;
  838. }
  839. }
  840. qdf_nbuf_peek_header(urb_context->buf, &data, &len);
  841. urb = urb_context->urb;
  842. usb_fill_bulk_urb(urb,
  843. recv_pipe->device->udev,
  844. recv_pipe->usb_pipe_handle,
  845. data,
  846. buffer_length,
  847. usb_hif_usb_recv_bundle_complete,
  848. urb_context);
  849. HIF_DBG("athusb bulk recv submit:%d, 0x%X (ep:0x%2.2X), %d bytes, buf:0x%p",
  850. recv_pipe->logical_pipe_num,
  851. recv_pipe->usb_pipe_handle,
  852. recv_pipe->ep_address, buffer_length,
  853. urb_context->buf);
  854. usb_hif_enqueue_pending_transfer(recv_pipe, urb_context);
  855. usb_status = usb_submit_urb(urb, GFP_ATOMIC);
  856. if (usb_status) {
  857. HIF_ERROR("athusb : usb bulk recv failed %d",
  858. usb_status);
  859. usb_hif_remove_pending_transfer(urb_context);
  860. usb_hif_free_urb_to_pipe(urb_context->pipe,
  861. urb_context);
  862. break;
  863. }
  864. }
  865. HIF_TRACE("-%s", __func__);
  866. }
  867. /**
  868. * usb_hif_prestart_recv_pipes() - post prestart recv urbs
  869. * @device: HIF device for which prestart recv urbs need to be posted
  870. *
  871. * Return: none
  872. */
  873. void usb_hif_prestart_recv_pipes(HIF_DEVICE_USB *device)
  874. {
  875. HIF_USB_PIPE *pipe = &device->pipes[HIF_RX_DATA_PIPE];
  876. /*
  877. * USB driver learn to support bundle or not until the firmware
  878. * download and ready. Only allocate some URBs for control message
  879. * communication during the initial phase then start the final
  880. * working pipe after all information understood.
  881. */
  882. usb_hif_post_recv_prestart_transfers(pipe, 8);
  883. }
  884. /**
  885. * usb_hif_start_recv_pipes() - start recv urbs
  886. * @device: HIF device for which recv urbs need to be posted
  887. *
  888. * This function is called after all prestart recv urbs are exhausted
  889. *
  890. * Return: none
  891. */
  892. void usb_hif_start_recv_pipes(HIF_DEVICE_USB *device)
  893. {
  894. HIF_USB_PIPE *pipe;
  895. uint32_t buf_len;
  896. HIF_ENTER();
  897. pipe = &device->pipes[HIF_RX_DATA_PIPE];
  898. pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
  899. HIF_TRACE("Post URBs to RX_DATA_PIPE: %d",
  900. device->pipes[HIF_RX_DATA_PIPE].urb_cnt);
  901. if (device->is_bundle_enabled) {
  902. usb_hif_post_recv_bundle_transfers(pipe,
  903. pipe->device->rx_bundle_buf_len);
  904. } else {
  905. buf_len = HIF_USB_RX_BUFFER_SIZE;
  906. usb_hif_post_recv_transfers(pipe, buf_len);
  907. }
  908. HIF_DBG("athusb bulk recv len %d", buf_len);
  909. if (!hif_usb_disable_rxdata2) {
  910. HIF_TRACE("Post URBs to RX_DATA2_PIPE: %d",
  911. device->pipes[HIF_RX_DATA2_PIPE].urb_cnt);
  912. pipe = &device->pipes[HIF_RX_DATA2_PIPE];
  913. pipe->urb_cnt_thresh = pipe->urb_alloc / 2;
  914. usb_hif_post_recv_transfers(pipe, HIF_USB_RX_BUFFER_SIZE);
  915. }
  916. HIF_EXIT();
  917. }
  918. /**
  919. * usb_hif_submit_ctrl_out() - send out a ctrl urb
  920. * @device: HIF device for which urb needs to be posted
  921. * @req: request value for the ctrl message
  922. * @value: USB message value
  923. * @index: USB message index value
  924. * @data: pointer to data containing ctrl message to send
  925. * @size: size of the control message to send
  926. *
  927. * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
  928. */
  929. QDF_STATUS usb_hif_submit_ctrl_out(HIF_DEVICE_USB *device,
  930. uint8_t req,
  931. uint16_t value,
  932. uint16_t index,
  933. void *data,
  934. uint32_t size)
  935. {
  936. int32_t result = 0;
  937. QDF_STATUS ret = QDF_STATUS_SUCCESS;
  938. uint8_t *buf = NULL;
  939. do {
  940. if (size > 0) {
  941. buf = qdf_mem_malloc(size);
  942. if (NULL == buf) {
  943. ret = QDF_STATUS_E_NOMEM;
  944. break;
  945. }
  946. qdf_mem_copy(buf, (uint8_t *) data, size);
  947. }
  948. HIF_DBG("ctrl-out req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d",
  949. req, value, index, size);
  950. result = usb_control_msg(device->udev,
  951. usb_sndctrlpipe(device->udev, 0),
  952. req,
  953. USB_DIR_OUT | USB_TYPE_VENDOR |
  954. USB_RECIP_DEVICE, value, index, buf,
  955. size, 2 * HZ);
  956. if (result < 0) {
  957. HIF_ERROR("%s failed,result = %d", __func__, result);
  958. ret = QDF_STATUS_E_FAILURE;
  959. }
  960. } while (false);
  961. if (buf != NULL)
  962. qdf_mem_free(buf);
  963. return ret;
  964. }
  965. /**
  966. * usb_hif_submit_ctrl_in() - recv a resonse to the ctrl message sent out
  967. * @device: HIF device for which urb needs to be received
  968. * @req: request value for the ctrl message
  969. * @value: USB message value
  970. * @index: USB message index value
  971. * @data: pointer to data containing ctrl message to be received
  972. * @size: size of the control message to be received
  973. *
  974. * Return: QDF_STATUS_SUCCESS if success else an appropriate QDF_STATUS error
  975. */
  976. QDF_STATUS usb_hif_submit_ctrl_in(HIF_DEVICE_USB *device,
  977. uint8_t req,
  978. uint16_t value,
  979. uint16_t index,
  980. void *data,
  981. uint32_t size)
  982. {
  983. int32_t result = 0;
  984. QDF_STATUS ret = QDF_STATUS_SUCCESS;
  985. uint8_t *buf = NULL;
  986. do {
  987. if (size > 0) {
  988. buf = qdf_mem_malloc(size);
  989. if (NULL == buf) {
  990. ret = QDF_STATUS_E_NOMEM;
  991. break;
  992. }
  993. }
  994. HIF_DBG("ctrl-in req:0x%2.2X, value:0x%4.4X index:0x%4.4X, datasize:%d",
  995. req, value, index, size);
  996. result = usb_control_msg(device->udev,
  997. usb_rcvctrlpipe(device->udev, 0),
  998. req,
  999. USB_DIR_IN | USB_TYPE_VENDOR |
  1000. USB_RECIP_DEVICE, value, index, buf,
  1001. size, 2 * HZ);
  1002. if (result < 0) {
  1003. HIF_ERROR("%s failed, result = %d", __func__, result);
  1004. ret = QDF_STATUS_E_FAILURE;
  1005. break;
  1006. }
  1007. qdf_mem_copy((uint8_t *) data, buf, size);
  1008. } while (false);
  1009. if (buf != NULL)
  1010. qdf_mem_free(buf);
  1011. return ret;
  1012. }
  1013. /**
  1014. * usb_hif_io_complete() - transmit call back for tx urb
  1015. * @pipe: pointer to HIF_USB_PIPE
  1016. *
  1017. * Return: none
  1018. */
  1019. void usb_hif_io_complete(HIF_USB_PIPE *pipe)
  1020. {
  1021. qdf_nbuf_t buf;
  1022. HIF_DEVICE_USB *device;
  1023. HTC_FRAME_HDR *HtcHdr;
  1024. uint8_t *data;
  1025. uint32_t len;
  1026. struct hif_usb_softc *sc = HIF_GET_USB_SOFTC(pipe->device);
  1027. device = pipe->device;
  1028. HIF_ENTER();
  1029. while ((buf = skb_dequeue(&pipe->io_comp_queue))) {
  1030. if (pipe->flags & HIF_USB_PIPE_FLAG_TX) {
  1031. HIF_DBG("+athusb xmit callback " "buf:0x%p", buf);
  1032. HtcHdr = (HTC_FRAME_HDR *)
  1033. qdf_nbuf_get_frag_vaddr(buf, 0);
  1034. #ifdef ATH_11AC_TXCOMPACT
  1035. /* ATH_11AC_TXCOMPACT does not support High Latency mode */
  1036. #else
  1037. device->htc_callbacks.txCompletionHandler(device->
  1038. htc_callbacks.
  1039. Context, buf,
  1040. HtcHdr->
  1041. EndpointID, 0);
  1042. #endif
  1043. HIF_DBG("-athusb xmit callback");
  1044. } else {
  1045. HIF_DBG("+athusb recv callback buf:" "0x%p", buf);
  1046. qdf_nbuf_peek_header(buf, &data, &len);
  1047. if (IS_FW_CRASH_DUMP(*((uint32_t *) data))) {
  1048. sc->fw_data = data;
  1049. sc->fw_data_len = len;
  1050. device->htc_callbacks.fwEventHandler(
  1051. device->htc_callbacks.Context,
  1052. QDF_STATUS_E_USB_ERROR);
  1053. qdf_nbuf_free(buf);
  1054. } else {
  1055. device->htc_callbacks.rxCompletionHandler(
  1056. device->htc_callbacks.Context, buf,
  1057. pipe->logical_pipe_num);
  1058. }
  1059. HIF_DBG("-athusb recv callback");
  1060. }
  1061. }
  1062. HIF_EXIT();
  1063. }
  1064. #ifdef HIF_USB_TASKLET
  1065. /**
  1066. * usb_hif_io_comp_tasklet() - per pipe tasklet routine
  1067. * @context: pointer to HIF USB pipe
  1068. *
  1069. * Return: none
  1070. */
  1071. void usb_hif_io_comp_tasklet(long unsigned int context)
  1072. {
  1073. HIF_USB_PIPE *pipe = (HIF_USB_PIPE *) context;
  1074. usb_hif_io_complete(pipe);
  1075. }
  1076. #else
  1077. /**
  1078. * usb_hif_io_comp_work() - per pipe work queue
  1079. * @work: pointer to struct work_struct
  1080. *
  1081. * Return: none
  1082. */
  1083. void usb_hif_io_comp_work(struct work_struct *work)
  1084. {
  1085. HIF_USB_PIPE *pipe = container_of(work, HIF_USB_PIPE, io_complete_work);
  1086. usb_hif_io_complete(pipe);
  1087. }
  1088. #endif