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 <recv_osdep.h>
23 #include <rtw_sreset.h>
25 static void interrupt_handler_8188eu(struct adapter
*adapt
, u16 pkt_len
, u8
*pbuf
)
27 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
29 if (pkt_len
!= INTERRUPT_MSG_FORMAT_LEN
) {
30 DBG_88E("%s Invalid interrupt content length (%d)!\n", __func__
, pkt_len
);
35 memcpy(&(haldata
->IntArray
[0]), &(pbuf
[USB_INTR_CONTENT_HISR_OFFSET
]), 4);
36 memcpy(&(haldata
->IntArray
[1]), &(pbuf
[USB_INTR_CONTENT_HISRE_OFFSET
]), 4);
40 memcpy(&(haldata
->C2hArray
[0]), &(pbuf
[USB_INTR_CONTENT_C2H_OFFSET
]), 16);
43 static int recvbuf2recvframe(struct adapter
*adapt
, struct sk_buff
*pskb
)
48 u32 pkt_offset
, skb_len
, alloc_sz
;
50 struct recv_stat
*prxstat
;
51 struct phy_stat
*pphy_status
= NULL
;
52 struct sk_buff
*pkt_copy
= NULL
;
53 struct recv_frame
*precvframe
= NULL
;
54 struct rx_pkt_attrib
*pattrib
= NULL
;
55 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
56 struct recv_priv
*precvpriv
= &adapt
->recvpriv
;
57 struct __queue
*pfree_recv_queue
= &precvpriv
->free_recv_queue
;
59 transfer_len
= (s32
)pskb
->len
;
62 prxstat
= (struct recv_stat
*)pbuf
;
63 pkt_cnt
= (le32_to_cpu(prxstat
->rxdw2
) >> 16) & 0xff;
66 RT_TRACE(_module_rtl871x_recv_c_
, _drv_info_
,
67 ("recvbuf2recvframe: rxdesc=offsset 0:0x%08x, 4:0x%08x, 8:0x%08x, C:0x%08x\n",
68 prxstat
->rxdw0
, prxstat
->rxdw1
, prxstat
->rxdw2
, prxstat
->rxdw4
));
70 prxstat
= (struct recv_stat
*)pbuf
;
72 precvframe
= rtw_alloc_recvframe(pfree_recv_queue
);
73 if (precvframe
== NULL
) {
74 RT_TRACE(_module_rtl871x_recv_c_
, _drv_err_
, ("recvbuf2recvframe: precvframe==NULL\n"));
75 DBG_88E("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __func__
, __LINE__
);
76 goto _exit_recvbuf2recvframe
;
79 INIT_LIST_HEAD(&precvframe
->list
);
82 update_recvframe_attrib_88e(precvframe
, prxstat
);
84 pattrib
= &precvframe
->attrib
;
86 if ((pattrib
->crc_err
) || (pattrib
->icv_err
)) {
87 DBG_88E("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __func__
, pattrib
->crc_err
, pattrib
->icv_err
);
89 rtw_free_recvframe(precvframe
, pfree_recv_queue
);
90 goto _exit_recvbuf2recvframe
;
93 if ((pattrib
->physt
) && (pattrib
->pkt_rpt_type
== NORMAL_RX
))
94 pphy_status
= (struct phy_stat
*)(pbuf
+ RXDESC_OFFSET
);
96 pkt_offset
= RXDESC_SIZE
+ pattrib
->drvinfo_sz
+ pattrib
->shift_sz
+ pattrib
->pkt_len
;
98 if ((pattrib
->pkt_len
<= 0) || (pkt_offset
> transfer_len
)) {
99 RT_TRACE(_module_rtl871x_recv_c_
, _drv_info_
, ("recvbuf2recvframe: pkt_len<=0\n"));
100 DBG_88E("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfoer_len\n", __func__
, __LINE__
);
101 rtw_free_recvframe(precvframe
, pfree_recv_queue
);
102 goto _exit_recvbuf2recvframe
;
105 /* Modified by Albert 20101213 */
106 /* For 8 bytes IP header alignment. */
107 if (pattrib
->qos
) /* Qos data, wireless lan header length is 26 */
112 skb_len
= pattrib
->pkt_len
;
114 /* for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */
115 /* modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */
116 if ((pattrib
->mfrag
== 1) && (pattrib
->frag_num
== 0)) {
120 alloc_sz
= skb_len
+ 14;
123 /* 6 is for IP header 8 bytes alignment in QoS packet case. */
124 /* 8 is for skb->data 4 bytes alignment. */
128 pkt_copy
= netdev_alloc_skb(adapt
->pnetdev
, alloc_sz
);
130 pkt_copy
->dev
= adapt
->pnetdev
;
131 precvframe
->pkt
= pkt_copy
;
132 precvframe
->rx_head
= pkt_copy
->data
;
133 precvframe
->rx_end
= pkt_copy
->data
+ alloc_sz
;
134 skb_reserve(pkt_copy
, 8 - ((size_t)(pkt_copy
->data
) & 7));/* force pkt_copy->data at 8-byte alignment address */
135 skb_reserve(pkt_copy
, shift_sz
);/* force ip_hdr at 8-byte alignment address according to shift_sz. */
136 memcpy(pkt_copy
->data
, (pbuf
+ pattrib
->drvinfo_sz
+ RXDESC_SIZE
), skb_len
);
137 precvframe
->rx_tail
= pkt_copy
->data
;
138 precvframe
->rx_data
= pkt_copy
->data
;
140 if ((pattrib
->mfrag
== 1) && (pattrib
->frag_num
== 0)) {
141 DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n");
142 rtw_free_recvframe(precvframe
, pfree_recv_queue
);
143 goto _exit_recvbuf2recvframe
;
145 precvframe
->pkt
= skb_clone(pskb
, GFP_ATOMIC
);
146 if (precvframe
->pkt
) {
147 precvframe
->rx_tail
= pbuf
+ pattrib
->drvinfo_sz
+ RXDESC_SIZE
;
148 precvframe
->rx_head
= precvframe
->rx_tail
;
149 precvframe
->rx_data
= precvframe
->rx_tail
;
150 precvframe
->rx_end
= pbuf
+ pattrib
->drvinfo_sz
+ RXDESC_SIZE
+ alloc_sz
;
152 DBG_88E("recvbuf2recvframe: skb_clone fail\n");
153 rtw_free_recvframe(precvframe
, pfree_recv_queue
);
154 goto _exit_recvbuf2recvframe
;
158 recvframe_put(precvframe
, skb_len
);
160 switch (haldata
->UsbRxAggMode
) {
163 pkt_offset
= (u16
)round_up(pkt_offset
, 128);
166 pkt_offset
= (u16
)round_up(pkt_offset
, 4);
168 case USB_RX_AGG_DISABLE
:
172 if (pattrib
->pkt_rpt_type
== NORMAL_RX
) { /* Normal rx packet */
174 update_recvframe_phyinfo_88e(precvframe
, (struct phy_stat
*)pphy_status
);
175 if (rtw_recv_entry(precvframe
) != _SUCCESS
) {
176 RT_TRACE(_module_rtl871x_recv_c_
, _drv_err_
,
177 ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
180 /* enqueue recvframe to txrtp queue */
181 if (pattrib
->pkt_rpt_type
== TX_REPORT1
) {
182 /* CCX-TXRPT ack for xmit mgmt frames. */
183 handle_txrpt_ccx_88e(adapt
, precvframe
->rx_data
);
184 } else if (pattrib
->pkt_rpt_type
== TX_REPORT2
) {
185 ODM_RA_TxRPT2Handle_8188E(
189 pattrib
->MacIDValidEntry
[0],
190 pattrib
->MacIDValidEntry
[1]
192 } else if (pattrib
->pkt_rpt_type
== HIS_REPORT
) {
193 interrupt_handler_8188eu(adapt
, pattrib
->pkt_len
, precvframe
->rx_data
);
195 rtw_free_recvframe(precvframe
, pfree_recv_queue
);
198 transfer_len
-= pkt_offset
;
203 if (transfer_len
> 0 && pkt_cnt
== 0)
204 pkt_cnt
= (le32_to_cpu(prxstat
->rxdw2
)>>16) & 0xff;
206 } while ((transfer_len
> 0) && (pkt_cnt
> 0));
208 _exit_recvbuf2recvframe
:
213 unsigned int ffaddr2pipehdl(struct dvobj_priv
*pdvobj
, u32 addr
)
215 unsigned int pipe
= 0, ep_num
= 0;
216 struct usb_device
*pusbd
= pdvobj
->pusbdev
;
218 if (addr
== RECV_BULK_IN_ADDR
) {
219 pipe
= usb_rcvbulkpipe(pusbd
, pdvobj
->RtInPipe
[0]);
220 } else if (addr
== RECV_INT_IN_ADDR
) {
221 pipe
= usb_rcvbulkpipe(pusbd
, pdvobj
->RtInPipe
[1]);
222 } else if (addr
< HW_QUEUE_ENTRY
) {
223 ep_num
= pdvobj
->Queue2Pipe
[addr
];
224 pipe
= usb_sndbulkpipe(pusbd
, ep_num
);
230 static int usbctrl_vendorreq(struct adapter
*adapt
, u8 request
, u16 value
, u16 index
, void *pdata
, u16 len
, u8 requesttype
)
232 struct dvobj_priv
*dvobjpriv
= adapter_to_dvobj(adapt
);
233 struct usb_device
*udev
= dvobjpriv
->pusbdev
;
238 int vendorreq_times
= 0;
240 if ((adapt
->bSurpriseRemoved
) || (adapt
->pwrctrlpriv
.pnp_bstop_trx
)) {
241 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usbctrl_vendorreq:(adapt->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
246 if (len
> MAX_VENDOR_REQ_CMD_SIZE
) {
247 DBG_88E("[%s] Buffer len error ,vendor request failed\n", __func__
);
252 _enter_critical_mutex(&dvobjpriv
->usb_vendor_req_mutex
, NULL
);
254 /* Acquire IO memory for vendorreq */
255 pIo_buf
= dvobjpriv
->usb_vendor_req_buf
;
257 if (pIo_buf
== NULL
) {
258 DBG_88E("[%s] pIo_buf == NULL\n", __func__
);
263 while (++vendorreq_times
<= MAX_USBCTRL_VENDORREQ_TIMES
) {
264 memset(pIo_buf
, 0, len
);
266 if (requesttype
== 0x01) {
267 pipe
= usb_rcvctrlpipe(udev
, 0);/* read_in */
268 reqtype
= REALTEK_USB_VENQT_READ
;
270 pipe
= usb_sndctrlpipe(udev
, 0);/* write_out */
271 reqtype
= REALTEK_USB_VENQT_WRITE
;
272 memcpy(pIo_buf
, pdata
, len
);
275 status
= usb_control_msg(udev
, pipe
, request
, reqtype
, value
, index
, pIo_buf
, len
, RTW_USB_CONTROL_MSG_TIMEOUT
);
277 if (status
== len
) { /* Success this control transfer. */
278 if (requesttype
== 0x01)
279 memcpy(pdata
, pIo_buf
, len
);
280 } else { /* error cases */
281 DBG_88E("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n",
282 value
, (requesttype
== 0x01) ? "read" : "write",
283 len
, status
, *(u32
*)pdata
, vendorreq_times
);
286 if (status
== (-ESHUTDOWN
) || status
== -ENODEV
) {
287 adapt
->bSurpriseRemoved
= true;
289 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
290 haldata
->srestpriv
.Wifi_Error_Status
= USB_VEN_REQ_CMD_FAIL
;
292 } else { /* status != len && status >= 0 */
294 if (requesttype
== 0x01) {
295 /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */
296 memcpy(pdata
, pIo_buf
, len
);
303 /* firmware download is checksumed, don't retry */
304 if ((value
>= FW_8188E_START_ADDRESS
&& value
<= FW_8188E_END_ADDRESS
) || status
== len
)
308 mutex_unlock(&dvobjpriv
->usb_vendor_req_mutex
);
313 u8
usb_read8(struct adapter
*adapter
, u32 addr
)
324 requesttype
= 0x01;/* read_in */
327 wvalue
= (u16
)(addr
&0x0000ffff);
330 usbctrl_vendorreq(adapter
, request
, wvalue
, index
, &data
, len
, requesttype
);
337 u16
usb_read16(struct adapter
*adapter
, u32 addr
)
347 requesttype
= 0x01;/* read_in */
349 wvalue
= (u16
)(addr
&0x0000ffff);
351 usbctrl_vendorreq(adapter
, request
, wvalue
, index
, &data
, len
, requesttype
);
353 return (u16
)(le32_to_cpu(data
)&0xffff);
356 u32
usb_read32(struct adapter
*adapter
, u32 addr
)
367 requesttype
= 0x01;/* read_in */
370 wvalue
= (u16
)(addr
&0x0000ffff);
373 usbctrl_vendorreq(adapter
, request
, wvalue
, index
, &data
, len
, requesttype
);
376 return le32_to_cpu(data
);
379 static void usb_read_port_complete(struct urb
*purb
, struct pt_regs
*regs
)
381 struct recv_buf
*precvbuf
= (struct recv_buf
*)purb
->context
;
382 struct adapter
*adapt
= (struct adapter
*)precvbuf
->adapter
;
383 struct recv_priv
*precvpriv
= &adapt
->recvpriv
;
385 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_read_port_complete!!!\n"));
387 precvpriv
->rx_pending_cnt
--;
389 if (adapt
->bSurpriseRemoved
|| adapt
->bDriverStopped
|| adapt
->bReadPortCancel
) {
390 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
,
391 ("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
392 adapt
->bDriverStopped
, adapt
->bSurpriseRemoved
));
394 precvbuf
->reuse
= true;
395 DBG_88E("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
396 __func__
, adapt
->bDriverStopped
,
397 adapt
->bSurpriseRemoved
, adapt
->bReadPortCancel
);
401 if (purb
->status
== 0) { /* SUCCESS */
402 if ((purb
->actual_length
> MAX_RECVBUF_SZ
) || (purb
->actual_length
< RXDESC_SIZE
)) {
403 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
,
404 ("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n"));
405 precvbuf
->reuse
= true;
406 usb_read_port(adapt
, precvpriv
->ff_hwaddr
, 0, (unsigned char *)precvbuf
);
407 DBG_88E("%s()-%d: RX Warning!\n", __func__
, __LINE__
);
409 skb_put(precvbuf
->pskb
, purb
->actual_length
);
410 skb_queue_tail(&precvpriv
->rx_skb_queue
, precvbuf
->pskb
);
412 if (skb_queue_len(&precvpriv
->rx_skb_queue
) <= 1)
413 tasklet_schedule(&precvpriv
->recv_tasklet
);
415 precvbuf
->pskb
= NULL
;
416 precvbuf
->reuse
= false;
417 usb_read_port(adapt
, precvpriv
->ff_hwaddr
, 0, (unsigned char *)precvbuf
);
420 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_read_port_complete : purb->status(%d) != 0\n", purb
->status
));
422 DBG_88E("###=> usb_read_port_complete => urb status(%d)\n", purb
->status
);
423 skb_put(precvbuf
->pskb
, purb
->actual_length
);
424 precvbuf
->pskb
= NULL
;
426 switch (purb
->status
) {
431 adapt
->bSurpriseRemoved
= true;
433 adapt
->bDriverStopped
= true;
434 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_read_port_complete:bDriverStopped=true\n"));
439 struct hal_data_8188e
*haldata
= GET_HAL_DATA(adapt
);
440 haldata
->srestpriv
.Wifi_Error_Status
= USB_READ_PORT_FAIL
;
442 precvbuf
->reuse
= true;
443 usb_read_port(adapt
, precvpriv
->ff_hwaddr
, 0, (unsigned char *)precvbuf
);
446 DBG_88E("ERROR: URB IS IN PROGRESS!\n");
454 u32
usb_read_port(struct adapter
*adapter
, u32 addr
, u32 cnt
, u8
*rmem
)
456 struct urb
*purb
= NULL
;
457 struct recv_buf
*precvbuf
= (struct recv_buf
*)rmem
;
458 struct dvobj_priv
*pdvobj
= adapter_to_dvobj(adapter
);
459 struct recv_priv
*precvpriv
= &adapter
->recvpriv
;
460 struct usb_device
*pusbd
= pdvobj
->pusbdev
;
464 size_t alignment
= 0;
468 if (adapter
->bDriverStopped
|| adapter
->bSurpriseRemoved
||
469 adapter
->pwrctrlpriv
.pnp_bstop_trx
) {
470 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
,
471 ("usb_read_port:(adapt->bDriverStopped ||adapt->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
476 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
,
477 ("usb_read_port:precvbuf==NULL\n"));
481 if ((!precvbuf
->reuse
) || (precvbuf
->pskb
== NULL
)) {
482 precvbuf
->pskb
= skb_dequeue(&precvpriv
->free_recv_skb_queue
);
483 if (NULL
!= precvbuf
->pskb
)
484 precvbuf
->reuse
= true;
487 /* re-assign for linux based on skb */
488 if ((!precvbuf
->reuse
) || (precvbuf
->pskb
== NULL
)) {
489 precvbuf
->pskb
= netdev_alloc_skb(adapter
->pnetdev
, MAX_RECVBUF_SZ
+ RECVBUFF_ALIGN_SZ
);
490 if (precvbuf
->pskb
== NULL
) {
491 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("init_recvbuf(): alloc_skb fail!\n"));
492 DBG_88E("#### usb_read_port() alloc_skb fail!#####\n");
496 tmpaddr
= (size_t)precvbuf
->pskb
->data
;
497 alignment
= tmpaddr
& (RECVBUFF_ALIGN_SZ
-1);
498 skb_reserve(precvbuf
->pskb
, (RECVBUFF_ALIGN_SZ
- alignment
));
499 } else { /* reuse skb */
500 precvbuf
->reuse
= false;
503 precvpriv
->rx_pending_cnt
++;
505 purb
= precvbuf
->purb
;
507 /* translate DMA FIFO addr to pipehandle */
508 pipe
= ffaddr2pipehdl(pdvobj
, addr
);
510 usb_fill_bulk_urb(purb
, pusbd
, pipe
,
511 precvbuf
->pskb
->data
,
513 usb_read_port_complete
,
514 precvbuf
);/* context is precvbuf */
516 err
= usb_submit_urb(purb
, GFP_ATOMIC
);
517 if ((err
) && (err
!= (-EPERM
))) {
518 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
,
519 ("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x",
521 DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",
529 void usb_read_port_cancel(struct adapter
*padapter
)
532 struct recv_buf
*precvbuf
;
533 precvbuf
= (struct recv_buf
*)padapter
->recvpriv
.precv_buf
;
535 DBG_88E("%s\n", __func__
);
537 padapter
->bReadPortCancel
= true;
539 for (i
= 0; i
< NR_RECVBUFF
; i
++) {
540 precvbuf
->reuse
= true;
542 usb_kill_urb(precvbuf
->purb
);
547 int usb_write8(struct adapter
*adapter
, u32 addr
, u8 val
)
558 requesttype
= 0x00;/* write_out */
560 wvalue
= (u16
)(addr
&0x0000ffff);
563 ret
= usbctrl_vendorreq(adapter
, request
, wvalue
, index
, &data
, len
, requesttype
);
567 int usb_write16(struct adapter
*adapter
, u32 addr
, u16 val
)
579 requesttype
= 0x00;/* write_out */
582 wvalue
= (u16
)(addr
&0x0000ffff);
585 data
= cpu_to_le32(val
& 0x0000ffff);
587 ret
= usbctrl_vendorreq(adapter
, request
, wvalue
, index
, &data
, len
, requesttype
);
593 int usb_write32(struct adapter
*adapter
, u32 addr
, u32 val
)
605 requesttype
= 0x00;/* write_out */
608 wvalue
= (u16
)(addr
&0x0000ffff);
610 data
= cpu_to_le32(val
);
612 ret
= usbctrl_vendorreq(adapter
, request
, wvalue
, index
, &data
, len
, requesttype
);
618 static void usb_write_port_complete(struct urb
*purb
, struct pt_regs
*regs
)
620 struct xmit_buf
*pxmitbuf
= (struct xmit_buf
*)purb
->context
;
621 struct adapter
*padapter
= pxmitbuf
->padapter
;
622 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
624 switch (pxmitbuf
->flags
) {
626 pxmitpriv
->voq_cnt
--;
629 pxmitpriv
->viq_cnt
--;
632 pxmitpriv
->beq_cnt
--;
635 pxmitpriv
->bkq_cnt
--;
638 #ifdef CONFIG_88EU_AP_MODE
639 rtw_chk_hi_queue_cmd(padapter
);
646 if (padapter
->bSurpriseRemoved
|| padapter
->bDriverStopped
||
647 padapter
->bWritePortCancel
) {
648 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
,
649 ("usb_write_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
650 padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
));
651 DBG_88E("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bWritePortCancel(%d) pxmitbuf->ext_tag(%x)\n",
652 __func__
, padapter
->bDriverStopped
,
653 padapter
->bSurpriseRemoved
, padapter
->bReadPortCancel
,
656 goto check_completion
;
660 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_write_port_complete : purb->status(%d) != 0\n", purb
->status
));
661 DBG_88E("###=> urb_write_port_complete status(%d)\n", purb
->status
);
662 if ((purb
->status
== -EPIPE
) || (purb
->status
== -EPROTO
)) {
663 sreset_set_wifi_error_status(padapter
, USB_WRITE_PORT_FAIL
);
664 } else if (purb
->status
== -EINPROGRESS
) {
665 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_write_port_complete: EINPROGESS\n"));
666 goto check_completion
;
667 } else if (purb
->status
== -ENOENT
) {
668 DBG_88E("%s: -ENOENT\n", __func__
);
669 goto check_completion
;
670 } else if (purb
->status
== -ECONNRESET
) {
671 DBG_88E("%s: -ECONNRESET\n", __func__
);
672 goto check_completion
;
673 } else if (purb
->status
== -ESHUTDOWN
) {
674 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_write_port_complete: ESHUTDOWN\n"));
675 padapter
->bDriverStopped
= true;
676 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_write_port_complete:bDriverStopped = true\n"));
677 goto check_completion
;
679 padapter
->bSurpriseRemoved
= true;
680 DBG_88E("bSurpriseRemoved = true\n");
681 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_write_port_complete:bSurpriseRemoved = true\n"));
683 goto check_completion
;
688 rtw_sctx_done_err(&pxmitbuf
->sctx
,
689 purb
->status
? RTW_SCTX_DONE_WRITE_PORT_ERR
:
690 RTW_SCTX_DONE_SUCCESS
);
692 rtw_free_xmitbuf(pxmitpriv
, pxmitbuf
);
694 tasklet_hi_schedule(&pxmitpriv
->xmit_tasklet
);
697 u32
usb_write_port(struct adapter
*padapter
, u32 addr
, u32 cnt
, u8
*wmem
)
703 struct urb
*purb
= NULL
;
704 struct dvobj_priv
*pdvobj
= adapter_to_dvobj(padapter
);
705 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
706 struct xmit_buf
*pxmitbuf
= (struct xmit_buf
*)wmem
;
707 struct xmit_frame
*pxmitframe
= (struct xmit_frame
*)pxmitbuf
->priv_data
;
708 struct usb_device
*pusbd
= pdvobj
->pusbdev
;
711 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("+usb_write_port\n"));
713 if ((padapter
->bDriverStopped
) || (padapter
->bSurpriseRemoved
) ||
714 (padapter
->pwrctrlpriv
.pnp_bstop_trx
)) {
715 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
,
716 ("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
717 rtw_sctx_done_err(&pxmitbuf
->sctx
, RTW_SCTX_DONE_TX_DENY
);
721 spin_lock_irqsave(&pxmitpriv
->lock
, irqL
);
725 pxmitpriv
->voq_cnt
++;
726 pxmitbuf
->flags
= VO_QUEUE_INX
;
729 pxmitpriv
->viq_cnt
++;
730 pxmitbuf
->flags
= VI_QUEUE_INX
;
733 pxmitpriv
->beq_cnt
++;
734 pxmitbuf
->flags
= BE_QUEUE_INX
;
737 pxmitpriv
->bkq_cnt
++;
738 pxmitbuf
->flags
= BK_QUEUE_INX
;
741 pxmitbuf
->flags
= HIGH_QUEUE_INX
;
744 pxmitbuf
->flags
= MGT_QUEUE_INX
;
748 spin_unlock_irqrestore(&pxmitpriv
->lock
, irqL
);
750 purb
= pxmitbuf
->pxmit_urb
[0];
752 /* translate DMA FIFO addr to pipehandle */
753 pipe
= ffaddr2pipehdl(pdvobj
, addr
);
755 usb_fill_bulk_urb(purb
, pusbd
, pipe
,
756 pxmitframe
->buf_addr
, /* pxmitbuf->pbuf */
758 usb_write_port_complete
,
759 pxmitbuf
);/* context is pxmitbuf */
761 status
= usb_submit_urb(purb
, GFP_ATOMIC
);
763 rtw_sctx_done_err(&pxmitbuf
->sctx
, RTW_SCTX_DONE_WRITE_PORT_ERR
);
764 DBG_88E("usb_write_port, status =%d\n", status
);
765 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("usb_write_port(): usb_submit_urb, status =%x\n", status
));
769 padapter
->bDriverStopped
= true;
779 /* We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */
781 RT_TRACE(_module_hci_ops_os_c_
, _drv_err_
, ("-usb_write_port\n"));
785 rtw_free_xmitbuf(pxmitpriv
, pxmitbuf
);
789 void usb_write_port_cancel(struct adapter
*padapter
)
792 struct xmit_buf
*pxmitbuf
= (struct xmit_buf
*)padapter
->xmitpriv
.pxmitbuf
;
794 DBG_88E("%s\n", __func__
);
796 padapter
->bWritePortCancel
= true;
798 for (i
= 0; i
< NR_XMITBUFF
; i
++) {
799 for (j
= 0; j
< 8; j
++) {
800 if (pxmitbuf
->pxmit_urb
[j
])
801 usb_kill_urb(pxmitbuf
->pxmit_urb
[j
]);
806 pxmitbuf
= (struct xmit_buf
*)padapter
->xmitpriv
.pxmit_extbuf
;
807 for (i
= 0; i
< NR_XMIT_EXTBUFF
; i
++) {
808 for (j
= 0; j
< 8; j
++) {
809 if (pxmitbuf
->pxmit_urb
[j
])
810 usb_kill_urb(pxmitbuf
->pxmit_urb
[j
]);
816 void rtl8188eu_recv_tasklet(void *priv
)
818 struct sk_buff
*pskb
;
819 struct adapter
*adapt
= priv
;
820 struct recv_priv
*precvpriv
= &adapt
->recvpriv
;
822 while (NULL
!= (pskb
= skb_dequeue(&precvpriv
->rx_skb_queue
))) {
823 if ((adapt
->bDriverStopped
) || (adapt
->bSurpriseRemoved
)) {
824 DBG_88E("recv_tasklet => bDriverStopped or bSurpriseRemoved\n");
825 dev_kfree_skb_any(pskb
);
828 recvbuf2recvframe(adapt
, pskb
);
829 skb_reset_tail_pointer(pskb
);
831 skb_queue_tail(&precvpriv
->free_recv_skb_queue
, pskb
);
835 void rtl8188eu_xmit_tasklet(void *priv
)
838 struct adapter
*adapt
= priv
;
839 struct xmit_priv
*pxmitpriv
= &adapt
->xmitpriv
;
841 if (check_fwstate(&adapt
->mlmepriv
, _FW_UNDER_SURVEY
))
845 if ((adapt
->bDriverStopped
) ||
846 (adapt
->bSurpriseRemoved
) ||
847 (adapt
->bWritePortCancel
)) {
848 DBG_88E("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
852 ret
= rtl8188eu_xmitframe_complete(adapt
, pxmitpriv
, NULL
);