1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 ******************************************************************************/
15 #define _USB_OPS_LINUX_C_
17 #include <drv_types.h>
18 #include <usb_ops_linux.h>
19 #include <rtw_sreset.h>
21 void rtl8723au_read_port_cancel(struct rtw_adapter *padapter)
23 struct recv_buf *precvbuf;
26 precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
28 DBG_8723A("%s\n", __func__);
30 padapter->bReadPortCancel = true;
32 for (i = 0; i < NR_RECVBUFF ; i++) {
34 usb_kill_urb(precvbuf->purb);
37 usb_kill_urb(padapter->recvpriv.int_in_urb);
40 static void usb_write_port23a_complete(struct urb *purb)
42 struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
43 struct rtw_adapter *padapter = pxmitbuf->padapter;
44 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
45 struct hal_data_8723a *phaldata;
48 switch (pxmitbuf->flags) {
50 #ifdef CONFIG_8723AU_AP_MODE
51 rtw_chk_hi_queue_cmd23a(padapter);
58 if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
59 padapter->bWritePortCancel) {
60 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
61 "usb_write_port23a_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
62 padapter->bDriverStopped, padapter->bSurpriseRemoved);
63 DBG_8723A("%s(): TX Warning! bDriverStopped(%d) OR "
64 "bSurpriseRemoved(%d) bWritePortCancel(%d) "
65 "pxmitbuf->ext_tag(%x)\n", __func__,
66 padapter->bDriverStopped, padapter->bSurpriseRemoved,
67 padapter->bReadPortCancel, pxmitbuf->ext_tag);
69 goto check_completion;
73 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
74 "usb_write_port23a_complete : purb->status(%d) != 0\n",
76 DBG_8723A("###=> urb_write_port_complete status(%d)\n",
78 if (purb->status == -EPIPE || purb->status == -EPROTO) {
79 } else if (purb->status == -EINPROGRESS) {
80 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
81 "usb_write_port23a_complete: EINPROGESS\n");
82 goto check_completion;
83 } else if (purb->status == -ENOENT) {
84 DBG_8723A("%s: -ENOENT\n", __func__);
85 goto check_completion;
86 } else if (purb->status == -ECONNRESET) {
87 DBG_8723A("%s: -ECONNRESET\n", __func__);
88 goto check_completion;
89 } else if (purb->status == -ESHUTDOWN) {
90 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
91 "usb_write_port23a_complete: ESHUTDOWN\n");
92 padapter->bDriverStopped = true;
93 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
94 "usb_write_port23a_complete:bDriverStopped = true\n");
95 goto check_completion;
97 padapter->bSurpriseRemoved = true;
98 DBG_8723A("bSurpriseRemoved = true\n");
99 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
100 "usb_write_port23a_complete:bSurpriseRemoved = true\n");
101 goto check_completion;
104 phaldata = GET_HAL_DATA(padapter);
105 phaldata->srestpriv.last_tx_complete_time = jiffies;
108 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
109 rtw23a_sctx_done_err(&pxmitbuf->sctx,
110 purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR :
111 RTW_SCTX_DONE_SUCCESS);
112 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
114 rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
116 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
119 int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt,
120 struct xmit_buf *pxmitbuf)
122 struct urb *purb = NULL;
123 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
124 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
125 struct xmit_frame *pxmitframe;
126 struct usb_device *pusbd = pdvobj->pusbdev;
128 unsigned int pipe, ep_num;
132 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, "+usb_write_port23a\n");
134 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
135 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
136 "%s:(padapter->bDriverStopped || padapter->bSurpriseRemoved)!!!\n",
138 rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
142 pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
143 spin_lock_irqsave(&pxmitpriv->lock, irqL);
147 pxmitbuf->flags = VO_QUEUE_INX;
150 pxmitbuf->flags = VI_QUEUE_INX;
153 pxmitbuf->flags = BE_QUEUE_INX;
156 pxmitbuf->flags = BK_QUEUE_INX;
159 pxmitbuf->flags = HIGH_QUEUE_INX;
162 pxmitbuf->flags = MGT_QUEUE_INX;
166 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
168 purb = pxmitbuf->pxmit_urb[0];
170 /* translate DMA FIFO addr to pipehandle */
171 ep_num = pdvobj->Queue2Pipe[addr];
172 pipe = usb_sndbulkpipe(pusbd, ep_num);
174 usb_fill_bulk_urb(purb, pusbd, pipe,
175 pxmitframe->buf_addr, /* pxmitbuf->pbuf */
176 cnt, usb_write_port23a_complete,
177 pxmitbuf);/* context is pxmitbuf */
179 status = usb_submit_urb(purb, GFP_ATOMIC);
181 struct hal_data_8723a *phaldata = GET_HAL_DATA(padapter);
182 phaldata->srestpriv.last_tx_time = jiffies;
184 rtw23a_sctx_done_err(&pxmitbuf->sctx,
185 RTW_SCTX_DONE_WRITE_PORT_ERR);
186 DBG_8723A("usb_write_port23a, status =%d\n", status);
187 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
188 "usb_write_port23a(): usb_submit_urb, status =%x\n",
193 padapter->bDriverStopped = true;
201 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, "-usb_write_port23a\n");
205 rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
210 void rtl8723au_write_port_cancel(struct rtw_adapter *padapter)
212 struct xmit_buf *pxmitbuf;
213 struct list_head *plist;
216 DBG_8723A("%s\n", __func__);
218 padapter->bWritePortCancel = true;
220 list_for_each(plist, &padapter->xmitpriv.xmitbuf_list) {
221 pxmitbuf = container_of(plist, struct xmit_buf, list2);
222 for (j = 0; j < 8; j++) {
223 if (pxmitbuf->pxmit_urb[j])
224 usb_kill_urb(pxmitbuf->pxmit_urb[j]);
227 list_for_each(plist, &padapter->xmitpriv.xmitextbuf_list) {
228 pxmitbuf = container_of(plist, struct xmit_buf, list2);
229 for (j = 0; j < 8; j++) {
230 if (pxmitbuf->pxmit_urb[j])
231 usb_kill_urb(pxmitbuf->pxmit_urb[j]);