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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 ******************************************************************************/
19 #define _USB_OPS_LINUX_C_
21 #include <drv_types.h>
22 #include <usb_ops_linux.h>
23 #include <rtw_sreset.h>
25 unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
27 unsigned int pipe = 0, ep_num = 0;
28 struct usb_device *pusbd = pdvobj->pusbdev;
30 if (addr == RECV_BULK_IN_ADDR) {
31 pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]);
32 } else if (addr == RECV_INT_IN_ADDR) {
33 pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[1]);
34 } else if (addr < HW_QUEUE_ENTRY) {
35 ep_num = pdvobj->Queue2Pipe[addr];
36 pipe = usb_sndbulkpipe(pusbd, ep_num);
42 struct zero_bulkout_context {
49 void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
53 void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
57 void usb_read_port_cancel(struct intf_hdl *pintfhdl)
60 struct recv_buf *precvbuf;
61 struct adapter *padapter = pintfhdl->padapter;
62 precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
64 DBG_88E("%s\n", __func__);
66 padapter->bReadPortCancel = true;
68 for (i = 0; i < NR_RECVBUFF; i++) {
69 precvbuf->reuse = true;
71 usb_kill_urb(precvbuf->purb);
76 static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
78 struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
79 struct adapter *padapter = pxmitbuf->padapter;
80 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
81 struct hal_data_8188e *haldata;
85 switch (pxmitbuf->flags) {
99 #ifdef CONFIG_88EU_AP_MODE
100 rtw_chk_hi_queue_cmd(padapter);
107 if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
108 padapter->bWritePortCancel) {
109 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
110 ("usb_write_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
111 padapter->bDriverStopped, padapter->bSurpriseRemoved));
112 DBG_88E("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bWritePortCancel(%d) pxmitbuf->ext_tag(%x)\n",
113 __func__, padapter->bDriverStopped,
114 padapter->bSurpriseRemoved, padapter->bReadPortCancel,
117 goto check_completion;
121 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete : purb->status(%d) != 0\n", purb->status));
122 DBG_88E("###=> urb_write_port_complete status(%d)\n", purb->status);
123 if ((purb->status == -EPIPE) || (purb->status == -EPROTO)) {
124 sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL);
125 } else if (purb->status == -EINPROGRESS) {
126 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete: EINPROGESS\n"));
127 goto check_completion;
128 } else if (purb->status == -ENOENT) {
129 DBG_88E("%s: -ENOENT\n", __func__);
130 goto check_completion;
131 } else if (purb->status == -ECONNRESET) {
132 DBG_88E("%s: -ECONNRESET\n", __func__);
133 goto check_completion;
134 } else if (purb->status == -ESHUTDOWN) {
135 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete: ESHUTDOWN\n"));
136 padapter->bDriverStopped = true;
137 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete:bDriverStopped = true\n"));
138 goto check_completion;
140 padapter->bSurpriseRemoved = true;
141 DBG_88E("bSurpriseRemoved = true\n");
142 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port_complete:bSurpriseRemoved = true\n"));
144 goto check_completion;
148 haldata = GET_HAL_DATA(padapter);
149 haldata->srestpriv.last_tx_complete_time = jiffies;
152 rtw_sctx_done_err(&pxmitbuf->sctx,
153 purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR :
154 RTW_SCTX_DONE_SUCCESS);
156 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
158 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
163 u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
169 struct urb *purb = NULL;
170 struct adapter *padapter = (struct adapter *)pintfhdl->padapter;
171 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
172 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
173 struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem;
174 struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
175 struct usb_device *pusbd = pdvobj->pusbdev;
179 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("+usb_write_port\n"));
181 if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||
182 (padapter->pwrctrlpriv.pnp_bstop_trx)) {
183 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
184 ("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
185 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
189 spin_lock_irqsave(&pxmitpriv->lock, irqL);
193 pxmitpriv->voq_cnt++;
194 pxmitbuf->flags = VO_QUEUE_INX;
197 pxmitpriv->viq_cnt++;
198 pxmitbuf->flags = VI_QUEUE_INX;
201 pxmitpriv->beq_cnt++;
202 pxmitbuf->flags = BE_QUEUE_INX;
205 pxmitpriv->bkq_cnt++;
206 pxmitbuf->flags = BK_QUEUE_INX;
209 pxmitbuf->flags = HIGH_QUEUE_INX;
212 pxmitbuf->flags = MGT_QUEUE_INX;
216 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
218 purb = pxmitbuf->pxmit_urb[0];
220 /* translate DMA FIFO addr to pipehandle */
221 pipe = ffaddr2pipehdl(pdvobj, addr);
223 usb_fill_bulk_urb(purb, pusbd, pipe,
224 pxmitframe->buf_addr, /* pxmitbuf->pbuf */
226 usb_write_port_complete,
227 pxmitbuf);/* context is pxmitbuf */
229 status = usb_submit_urb(purb, GFP_ATOMIC);
231 struct hal_data_8188e *haldata = GET_HAL_DATA(padapter);
233 haldata->srestpriv.last_tx_time = jiffies;
235 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
236 DBG_88E("usb_write_port, status =%d\n", status);
237 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port(): usb_submit_urb, status =%x\n", status));
241 padapter->bDriverStopped = true;
251 /* We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */
253 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("-usb_write_port\n"));
257 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
262 void usb_write_port_cancel(struct intf_hdl *pintfhdl)
265 struct adapter *padapter = pintfhdl->padapter;
266 struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf;
268 DBG_88E("%s\n", __func__);
270 padapter->bWritePortCancel = true;
272 for (i = 0; i < NR_XMITBUFF; i++) {
273 for (j = 0; j < 8; j++) {
274 if (pxmitbuf->pxmit_urb[j])
275 usb_kill_urb(pxmitbuf->pxmit_urb[j]);
280 pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmit_extbuf;
281 for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
282 for (j = 0; j < 8; j++) {
283 if (pxmitbuf->pxmit_urb[j])
284 usb_kill_urb(pxmitbuf->pxmit_urb[j]);