1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _USB_OPS_LINUX_C_
8 
9 #include <drv_types.h>
10 #include <recv_osdep.h>
11 #include <rtw_sreset.h>
12 
interrupt_handler_8188eu(struct adapter * adapt,u16 pkt_len,u8 * pbuf)13 static void interrupt_handler_8188eu(struct adapter *adapt, u16 pkt_len, u8 *pbuf)
14 {
15 	struct hal_data_8188e *haldata = adapt->HalData;
16 
17 	if (pkt_len != INTERRUPT_MSG_FORMAT_LEN) {
18 		DBG_88E("%s Invalid interrupt content length (%d)!\n", __func__, pkt_len);
19 		return;
20 	}
21 
22 	/*  HISR */
23 	memcpy(&haldata->IntArray[0], &pbuf[USB_INTR_CONTENT_HISR_OFFSET], 4);
24 	memcpy(&haldata->IntArray[1], &pbuf[USB_INTR_CONTENT_HISRE_OFFSET], 4);
25 
26 	/*  C2H Event */
27 	if (pbuf[0] != 0)
28 		memcpy(&haldata->C2hArray[0],
29 		       &pbuf[USB_INTR_CONTENT_C2H_OFFSET], 16);
30 }
31 
recvbuf2recvframe(struct adapter * adapt,struct sk_buff * pskb)32 static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
33 {
34 	u8 *pbuf;
35 	u8 shift_sz = 0;
36 	u16 pkt_cnt;
37 	u32 pkt_offset, skb_len, alloc_sz;
38 	s32 transfer_len;
39 	struct recv_stat *prxstat;
40 	struct phy_stat *pphy_status = NULL;
41 	struct sk_buff *pkt_copy = NULL;
42 	struct recv_frame *precvframe = NULL;
43 	struct rx_pkt_attrib *pattrib = NULL;
44 	struct hal_data_8188e *haldata = adapt->HalData;
45 	struct recv_priv *precvpriv = &adapt->recvpriv;
46 	struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
47 
48 	transfer_len = (s32)pskb->len;
49 	pbuf = pskb->data;
50 
51 	prxstat = (struct recv_stat *)pbuf;
52 	pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
53 
54 	do {
55 		RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
56 			 ("%s: rxdesc=offsset 0:0x%08x, 4:0x%08x, 8:0x%08x, C:0x%08x\n",
57 			  __func__, prxstat->rxdw0, prxstat->rxdw1,
58 			  prxstat->rxdw2, prxstat->rxdw4));
59 
60 		prxstat = (struct recv_stat *)pbuf;
61 
62 		precvframe = rtw_alloc_recvframe(pfree_recv_queue);
63 		if (!precvframe) {
64 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
65 				 ("%s: precvframe==NULL\n", __func__));
66 			DBG_88E("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __func__, __LINE__);
67 			goto _exit_recvbuf2recvframe;
68 		}
69 
70 		INIT_LIST_HEAD(&precvframe->list);
71 
72 		update_recvframe_attrib_88e(precvframe, prxstat);
73 
74 		pattrib = &precvframe->attrib;
75 
76 		if ((pattrib->crc_err) || (pattrib->icv_err)) {
77 			DBG_88E("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __func__, pattrib->crc_err, pattrib->icv_err);
78 
79 			rtw_free_recvframe(precvframe, pfree_recv_queue);
80 			goto _exit_recvbuf2recvframe;
81 		}
82 
83 		if ((pattrib->physt) && (pattrib->pkt_rpt_type == NORMAL_RX))
84 			pphy_status = (struct phy_stat *)(pbuf + RXDESC_OFFSET);
85 
86 		pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
87 
88 		if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) {
89 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
90 				 ("%s: pkt_len<=0\n", __func__));
91 			DBG_88E("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfer_len\n", __func__, __LINE__);
92 			rtw_free_recvframe(precvframe, pfree_recv_queue);
93 			goto _exit_recvbuf2recvframe;
94 		}
95 
96 		/*	Modified by Albert 20101213 */
97 		/*	For 8 bytes IP header alignment. */
98 		if (pattrib->qos)	/*	Qos data, wireless lan header length is 26 */
99 			shift_sz = 6;
100 		else
101 			shift_sz = 0;
102 
103 		skb_len = pattrib->pkt_len;
104 
105 		/*  for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */
106 		/*  modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */
107 		if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
108 			if (skb_len <= 1650)
109 				alloc_sz = 1664;
110 			else
111 				alloc_sz = skb_len + 14;
112 		} else {
113 			alloc_sz = skb_len;
114 			/*	6 is for IP header 8 bytes alignment in QoS packet case. */
115 			/*	8 is for skb->data 4 bytes alignment. */
116 			alloc_sz += 14;
117 		}
118 
119 		pkt_copy = netdev_alloc_skb(adapt->pnetdev, alloc_sz);
120 		if (pkt_copy) {
121 			pkt_copy->dev = adapt->pnetdev;
122 			precvframe->pkt = pkt_copy;
123 			skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */
124 			skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */
125 			skb_put_data(pkt_copy, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
126 		} else {
127 			DBG_88E("%s: alloc_skb fail , drop frag frame\n",
128 				__func__);
129 			rtw_free_recvframe(precvframe, pfree_recv_queue);
130 			goto _exit_recvbuf2recvframe;
131 		}
132 
133 		switch (haldata->UsbRxAggMode) {
134 		case USB_RX_AGG_DMA:
135 		case USB_RX_AGG_MIX:
136 			pkt_offset = (u16)round_up(pkt_offset, 128);
137 			break;
138 		case USB_RX_AGG_USB:
139 			pkt_offset = (u16)round_up(pkt_offset, 4);
140 			break;
141 		case USB_RX_AGG_DISABLE:
142 		default:
143 			break;
144 		}
145 		if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */
146 			if (pattrib->physt)
147 				update_recvframe_phyinfo_88e(precvframe, pphy_status);
148 			if (rtw_recv_entry(precvframe) != _SUCCESS) {
149 				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
150 					 ("%s: rtw_recv_entry(precvframe) != _SUCCESS\n",
151 					 __func__));
152 			}
153 		} else if (pattrib->pkt_rpt_type == TX_REPORT1) {
154 			/* CCX-TXRPT ack for xmit mgmt frames. */
155 			handle_txrpt_ccx_88e(adapt, precvframe->pkt->data);
156 			rtw_free_recvframe(precvframe, pfree_recv_queue);
157 		} else if (pattrib->pkt_rpt_type == TX_REPORT2) {
158 			ODM_RA_TxRPT2Handle_8188E(&haldata->odmpriv,
159 						  precvframe->pkt->data,
160 						  pattrib->pkt_len,
161 						  pattrib->MacIDValidEntry[0],
162 						  pattrib->MacIDValidEntry[1]);
163 			rtw_free_recvframe(precvframe, pfree_recv_queue);
164 		} else if (pattrib->pkt_rpt_type == HIS_REPORT) {
165 			interrupt_handler_8188eu(adapt, pattrib->pkt_len, precvframe->pkt->data);
166 			rtw_free_recvframe(precvframe, pfree_recv_queue);
167 		}
168 		pkt_cnt--;
169 		transfer_len -= pkt_offset;
170 		pbuf += pkt_offset;
171 		precvframe = NULL;
172 		pkt_copy = NULL;
173 
174 		if (transfer_len > 0 && pkt_cnt == 0)
175 			pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
176 
177 	} while ((transfer_len > 0) && (pkt_cnt > 0));
178 
179 _exit_recvbuf2recvframe:
180 
181 	return _SUCCESS;
182 }
183 
ffaddr2pipehdl(struct dvobj_priv * pdvobj,u32 addr)184 unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
185 {
186 	unsigned int pipe = 0, ep_num = 0;
187 	struct usb_device *pusbd = pdvobj->pusbdev;
188 
189 	if (addr == RECV_BULK_IN_ADDR) {
190 		pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]);
191 	} else if (addr == RECV_INT_IN_ADDR) {
192 		pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[1]);
193 	} else if (addr < HW_QUEUE_ENTRY) {
194 		ep_num = pdvobj->Queue2Pipe[addr];
195 		pipe = usb_sndbulkpipe(pusbd, ep_num);
196 	}
197 
198 	return pipe;
199 }
200 
usbctrl_vendorreq(struct adapter * adapt,u8 request,u16 value,u16 index,void * pdata,u16 len,u8 requesttype)201 static int usbctrl_vendorreq(struct adapter *adapt, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
202 {
203 	struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt);
204 	struct usb_device *udev = dvobjpriv->pusbdev;
205 	unsigned int pipe;
206 	int status = 0;
207 	u8 reqtype;
208 	u8 *pIo_buf;
209 	int vendorreq_times = 0;
210 
211 	if ((adapt->bSurpriseRemoved) || (adapt->pwrctrlpriv.pnp_bstop_trx)) {
212 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
213 			 ("%s:(adapt->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",
214 			  __func__));
215 		status = -EPERM;
216 		goto exit;
217 	}
218 
219 	if (len > MAX_VENDOR_REQ_CMD_SIZE) {
220 		DBG_88E("[%s] Buffer len error ,vendor request failed\n", __func__);
221 		status = -EINVAL;
222 		goto exit;
223 	}
224 
225 	if (mutex_lock_interruptible(&dvobjpriv->usb_vendor_req_mutex)) {
226 		status = -ERESTARTSYS;
227 		goto exit;
228 	}
229 
230 	/*  Acquire IO memory for vendorreq */
231 	pIo_buf = kmalloc(MAX_USB_IO_CTL_SIZE, GFP_ATOMIC);
232 
233 	if (!pIo_buf) {
234 		status = -ENOMEM;
235 		goto release_mutex;
236 	}
237 
238 	while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) {
239 		memset(pIo_buf, 0, len);
240 
241 		if (requesttype == 0x01) {
242 			pipe = usb_rcvctrlpipe(udev, 0);/* read_in */
243 			reqtype =  REALTEK_USB_VENQT_READ;
244 		} else {
245 			pipe = usb_sndctrlpipe(udev, 0);/* write_out */
246 			reqtype =  REALTEK_USB_VENQT_WRITE;
247 			memcpy(pIo_buf, pdata, len);
248 		}
249 
250 		status = usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT);
251 
252 		if (status == len) {   /*  Success this control transfer. */
253 			if (requesttype == 0x01)
254 				memcpy(pdata, pIo_buf,  len);
255 		} else { /*  error cases */
256 			DBG_88E("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n",
257 				value, (requesttype == 0x01) ? "read" : "write",
258 				len, status, *(u32 *)pdata, vendorreq_times);
259 
260 			if (status < 0) {
261 				if (status == (-ESHUTDOWN) || status == -ENODEV)
262 					adapt->bSurpriseRemoved = true;
263 				else
264 					adapt->HalData->srestpriv.wifi_error_status = USB_VEN_REQ_CMD_FAIL;
265 			} else { /*  status != len && status >= 0 */
266 				if (status > 0) {
267 					if (requesttype == 0x01) {
268 						/*  For Control read transfer, we have to copy the read data from pIo_buf to pdata. */
269 						memcpy(pdata, pIo_buf,  len);
270 					}
271 				}
272 			}
273 		}
274 
275 		/*  firmware download is checksummed, don't retry */
276 		if ((value >= FW_8188E_START_ADDRESS && value <= FW_8188E_END_ADDRESS) || status == len)
277 			break;
278 	}
279 	kfree(pIo_buf);
280 
281 release_mutex:
282 	mutex_unlock(&dvobjpriv->usb_vendor_req_mutex);
283 exit:
284 	return status;
285 }
286 
usb_read8(struct adapter * adapter,u32 addr)287 u8 usb_read8(struct adapter *adapter, u32 addr)
288 {
289 	u8 request;
290 	u8 requesttype;
291 	u16 wvalue;
292 	u16 index;
293 	u16 len;
294 	u8 data = 0;
295 
296 	request = 0x05;
297 	requesttype = 0x01;/* read_in */
298 	index = 0;/* n/a */
299 
300 	wvalue = (u16)(addr & 0x0000ffff);
301 	len = 1;
302 
303 	usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
304 
305 	return data;
306 }
307 
usb_read16(struct adapter * adapter,u32 addr)308 u16 usb_read16(struct adapter *adapter, u32 addr)
309 {
310 	u8 request;
311 	u8 requesttype;
312 	u16 wvalue;
313 	u16 index;
314 	u16 len;
315 	__le32 data;
316 
317 	request = 0x05;
318 	requesttype = 0x01;/* read_in */
319 	index = 0;/* n/a */
320 	wvalue = (u16)(addr & 0x0000ffff);
321 	len = 2;
322 	usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
323 
324 	return (u16)(le32_to_cpu(data) & 0xffff);
325 }
326 
usb_read32(struct adapter * adapter,u32 addr)327 u32 usb_read32(struct adapter *adapter, u32 addr)
328 {
329 	u8 request;
330 	u8 requesttype;
331 	u16 wvalue;
332 	u16 index;
333 	u16 len;
334 	__le32 data;
335 
336 	request = 0x05;
337 	requesttype = 0x01;/* read_in */
338 	index = 0;/* n/a */
339 
340 	wvalue = (u16)(addr & 0x0000ffff);
341 	len = 4;
342 
343 	usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
344 
345 	return le32_to_cpu(data);
346 }
347 
usb_read_port_complete(struct urb * purb,struct pt_regs * regs)348 static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
349 {
350 	struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
351 	struct adapter *adapt = (struct adapter *)precvbuf->adapter;
352 	struct recv_priv *precvpriv = &adapt->recvpriv;
353 
354 	RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s!!!\n", __func__));
355 
356 	if (adapt->bSurpriseRemoved || adapt->bDriverStopped || adapt->bReadPortCancel) {
357 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
358 			 ("%s:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
359 			 __func__, adapt->bDriverStopped,
360 			 adapt->bSurpriseRemoved));
361 
362 		precvbuf->reuse = true;
363 		DBG_88E("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
364 			__func__, adapt->bDriverStopped,
365 			adapt->bSurpriseRemoved, adapt->bReadPortCancel);
366 		return;
367 	}
368 
369 	if (purb->status == 0) { /* SUCCESS */
370 		if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) {
371 			RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
372 				 ("%s: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n",
373 				 __func__));
374 			precvbuf->reuse = true;
375 			usb_read_port(adapt, RECV_BULK_IN_ADDR, precvbuf);
376 			DBG_88E("%s()-%d: RX Warning!\n", __func__, __LINE__);
377 		} else {
378 			skb_put(precvbuf->pskb, purb->actual_length);
379 			skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
380 
381 			if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1)
382 				tasklet_schedule(&precvpriv->recv_tasklet);
383 
384 			precvbuf->pskb = NULL;
385 			precvbuf->reuse = false;
386 			usb_read_port(adapt, RECV_BULK_IN_ADDR, precvbuf);
387 		}
388 	} else {
389 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
390 			 ("%s : purb->status(%d) != 0\n",
391 			  __func__, purb->status));
392 
393 		DBG_88E("###=> %s => urb status(%d)\n", __func__, purb->status);
394 		skb_put(precvbuf->pskb, purb->actual_length);
395 		precvbuf->pskb = NULL;
396 
397 		switch (purb->status) {
398 		case -EINVAL:
399 		case -EPIPE:
400 		case -ENODEV:
401 		case -ESHUTDOWN:
402 			adapt->bSurpriseRemoved = true;
403 			fallthrough;
404 		case -ENOENT:
405 			adapt->bDriverStopped = true;
406 			RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
407 				 ("%s:bDriverStopped=true\n", __func__));
408 			break;
409 		case -EPROTO:
410 		case -EOVERFLOW:
411 			adapt->HalData->srestpriv.wifi_error_status = USB_READ_PORT_FAIL;
412 			precvbuf->reuse = true;
413 			usb_read_port(adapt, RECV_BULK_IN_ADDR, precvbuf);
414 			break;
415 		case -EINPROGRESS:
416 			DBG_88E("ERROR: URB IS IN PROGRESS!\n");
417 			break;
418 		default:
419 			break;
420 		}
421 	}
422 }
423 
usb_read_port(struct adapter * adapter,u32 addr,struct recv_buf * precvbuf)424 u32 usb_read_port(struct adapter *adapter, u32 addr, struct recv_buf *precvbuf)
425 {
426 	struct urb *purb = NULL;
427 	struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter);
428 	struct recv_priv *precvpriv = &adapter->recvpriv;
429 	struct usb_device *pusbd = pdvobj->pusbdev;
430 	int err;
431 	unsigned int pipe;
432 	u32 ret = _SUCCESS;
433 
434 	if (adapter->bDriverStopped || adapter->bSurpriseRemoved ||
435 	    adapter->pwrctrlpriv.pnp_bstop_trx) {
436 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
437 			 ("%s:(adapt->bDriverStopped ||adapt->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",
438 			  __func__));
439 		return _FAIL;
440 	}
441 
442 	if (!precvbuf) {
443 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
444 			 ("%s:precvbuf==NULL\n", __func__));
445 		return _FAIL;
446 	}
447 
448 	if (!precvbuf->reuse || !precvbuf->pskb) {
449 		precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
450 		if (precvbuf->pskb)
451 			precvbuf->reuse = true;
452 	}
453 
454 	/* re-assign for linux based on skb */
455 	if (!precvbuf->reuse || !precvbuf->pskb) {
456 		precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ);
457 		if (!precvbuf->pskb) {
458 			RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("init_recvbuf(): alloc_skb fail!\n"));
459 			DBG_88E("#### %s() alloc_skb fail!#####\n", __func__);
460 			return _FAIL;
461 		}
462 	} else { /* reuse skb */
463 		precvbuf->reuse = false;
464 	}
465 
466 	purb = precvbuf->purb;
467 
468 	/* translate DMA FIFO addr to pipehandle */
469 	pipe = ffaddr2pipehdl(pdvobj, addr);
470 
471 	usb_fill_bulk_urb(purb, pusbd, pipe,
472 			  precvbuf->pskb->data,
473 			  MAX_RECVBUF_SZ,
474 			  usb_read_port_complete,
475 			  precvbuf);/* context is precvbuf */
476 
477 	err = usb_submit_urb(purb, GFP_ATOMIC);
478 	if ((err) && (err != (-EPERM))) {
479 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
480 			 ("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x",
481 			 err, purb->status));
482 		DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",
483 			err, purb->status);
484 		ret = _FAIL;
485 	}
486 
487 	return ret;
488 }
489 
rtw_hal_inirp_deinit(struct adapter * padapter)490 void rtw_hal_inirp_deinit(struct adapter *padapter)
491 {
492 	int i;
493 	struct recv_buf *precvbuf;
494 
495 	precvbuf = padapter->recvpriv.precv_buf;
496 
497 	DBG_88E("%s\n", __func__);
498 
499 	padapter->bReadPortCancel = true;
500 
501 	for (i = 0; i < NR_RECVBUFF; i++) {
502 		precvbuf->reuse = true;
503 		if (precvbuf->purb)
504 			usb_kill_urb(precvbuf->purb);
505 		precvbuf++;
506 	}
507 }
508 
usb_write8(struct adapter * adapter,u32 addr,u8 val)509 int usb_write8(struct adapter *adapter, u32 addr, u8 val)
510 {
511 	u8 request;
512 	u8 requesttype;
513 	u16 wvalue;
514 	u16 index;
515 	u16 len;
516 	u8 data;
517 
518 	request = 0x05;
519 	requesttype = 0x00;/* write_out */
520 	index = 0;/* n/a */
521 	wvalue = (u16)(addr & 0x0000ffff);
522 	len = 1;
523 	data = val;
524 	return usbctrl_vendorreq(adapter, request, wvalue,
525 				 index, &data, len, requesttype);
526 }
527 
usb_write16(struct adapter * adapter,u32 addr,u16 val)528 int usb_write16(struct adapter *adapter, u32 addr, u16 val)
529 {
530 	u8 request;
531 	u8 requesttype;
532 	u16 wvalue;
533 	u16 index;
534 	u16 len;
535 	__le32 data;
536 
537 	request = 0x05;
538 	requesttype = 0x00;/* write_out */
539 	index = 0;/* n/a */
540 
541 	wvalue = (u16)(addr & 0x0000ffff);
542 	len = 2;
543 
544 	data = cpu_to_le32(val & 0x0000ffff);
545 
546 	return usbctrl_vendorreq(adapter, request, wvalue,
547 				 index, &data, len, requesttype);
548 }
549 
usb_write32(struct adapter * adapter,u32 addr,u32 val)550 int usb_write32(struct adapter *adapter, u32 addr, u32 val)
551 {
552 	u8 request;
553 	u8 requesttype;
554 	u16 wvalue;
555 	u16 index;
556 	u16 len;
557 	__le32 data;
558 
559 	request = 0x05;
560 	requesttype = 0x00;/* write_out */
561 	index = 0;/* n/a */
562 
563 	wvalue = (u16)(addr & 0x0000ffff);
564 	len = 4;
565 	data = cpu_to_le32(val);
566 
567 	return usbctrl_vendorreq(adapter, request, wvalue,
568 				 index, &data, len, requesttype);
569 }
570 
usb_write_port_complete(struct urb * purb,struct pt_regs * regs)571 static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
572 {
573 	struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
574 	struct adapter *padapter = pxmitbuf->padapter;
575 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
576 
577 	switch (pxmitbuf->flags) {
578 	case VO_QUEUE_INX:
579 		pxmitpriv->voq_cnt--;
580 		break;
581 	case VI_QUEUE_INX:
582 		pxmitpriv->viq_cnt--;
583 		break;
584 	case BE_QUEUE_INX:
585 		pxmitpriv->beq_cnt--;
586 		break;
587 	case BK_QUEUE_INX:
588 		pxmitpriv->bkq_cnt--;
589 		break;
590 	case HIGH_QUEUE_INX:
591 #ifdef CONFIG_88EU_AP_MODE
592 		rtw_chk_hi_queue_cmd(padapter);
593 #endif
594 		break;
595 	default:
596 		break;
597 	}
598 
599 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
600 	    padapter->bWritePortCancel) {
601 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
602 			 ("%s:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
603 			  __func__, padapter->bDriverStopped,
604 			  padapter->bSurpriseRemoved));
605 		DBG_88E("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bWritePortCancel(%d) pxmitbuf->ext_tag(%x)\n",
606 			__func__, padapter->bDriverStopped,
607 			padapter->bSurpriseRemoved, padapter->bReadPortCancel,
608 			pxmitbuf->ext_tag);
609 
610 		goto check_completion;
611 	}
612 
613 	if (purb->status) {
614 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
615 			 ("%s : purb->status(%d) != 0\n",
616 			  __func__, purb->status));
617 		DBG_88E("###=> %s status(%d)\n", __func__, purb->status);
618 		if ((purb->status == -EPIPE) || (purb->status == -EPROTO)) {
619 			sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL);
620 		} else if (purb->status == -EINPROGRESS) {
621 			RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
622 				 ("%s: EINPROGRESS\n", __func__));
623 			goto check_completion;
624 		} else if (purb->status == -ENOENT) {
625 			DBG_88E("%s: -ENOENT\n", __func__);
626 			goto check_completion;
627 		} else if (purb->status == -ECONNRESET) {
628 			DBG_88E("%s: -ECONNRESET\n", __func__);
629 			goto check_completion;
630 		} else if (purb->status == -ESHUTDOWN) {
631 			RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
632 				 ("%s: ESHUTDOWN\n", __func__));
633 			padapter->bDriverStopped = true;
634 			RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
635 				 ("%s:bDriverStopped = true\n", __func__));
636 			goto check_completion;
637 		} else {
638 			padapter->bSurpriseRemoved = true;
639 			DBG_88E("bSurpriseRemoved = true\n");
640 			RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
641 				 ("%s:bSurpriseRemoved = true\n", __func__));
642 			goto check_completion;
643 		}
644 	}
645 
646 check_completion:
647 	rtw_sctx_done_err(&pxmitbuf->sctx,
648 			  purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR :
649 			  RTW_SCTX_DONE_SUCCESS);
650 
651 	rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
652 
653 	tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
654 }
655 
usb_write_port(struct adapter * padapter,u32 addr,u32 cnt,struct xmit_buf * xmitbuf)656 u32 usb_write_port(struct adapter *padapter, u32 addr, u32 cnt, struct xmit_buf *xmitbuf)
657 {
658 	unsigned long irqL;
659 	unsigned int pipe;
660 	int status;
661 	u32 ret = _FAIL;
662 	struct urb *purb = NULL;
663 	struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
664 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
665 	struct xmit_frame *pxmitframe = (struct xmit_frame *)xmitbuf->priv_data;
666 	struct usb_device *pusbd = pdvobj->pusbdev;
667 
668 	RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("+%s\n", __func__));
669 
670 	if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||
671 	    (padapter->pwrctrlpriv.pnp_bstop_trx)) {
672 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
673 			 ("%s:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",
674 			  __func__));
675 		rtw_sctx_done_err(&xmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
676 		goto exit;
677 	}
678 
679 	spin_lock_irqsave(&pxmitpriv->lock, irqL);
680 
681 	switch (addr) {
682 	case VO_QUEUE_INX:
683 		pxmitpriv->voq_cnt++;
684 		xmitbuf->flags = VO_QUEUE_INX;
685 		break;
686 	case VI_QUEUE_INX:
687 		pxmitpriv->viq_cnt++;
688 		xmitbuf->flags = VI_QUEUE_INX;
689 		break;
690 	case BE_QUEUE_INX:
691 		pxmitpriv->beq_cnt++;
692 		xmitbuf->flags = BE_QUEUE_INX;
693 		break;
694 	case BK_QUEUE_INX:
695 		pxmitpriv->bkq_cnt++;
696 		xmitbuf->flags = BK_QUEUE_INX;
697 		break;
698 	case HIGH_QUEUE_INX:
699 		xmitbuf->flags = HIGH_QUEUE_INX;
700 		break;
701 	default:
702 		xmitbuf->flags = MGT_QUEUE_INX;
703 		break;
704 	}
705 
706 	spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
707 
708 	purb	= xmitbuf->pxmit_urb[0];
709 
710 	/* translate DMA FIFO addr to pipehandle */
711 	pipe = ffaddr2pipehdl(pdvobj, addr);
712 
713 	usb_fill_bulk_urb(purb, pusbd, pipe,
714 			  pxmitframe->buf_addr, /*  xmitbuf->pbuf */
715 			  cnt,
716 			  usb_write_port_complete,
717 			  xmitbuf);/* context is xmitbuf */
718 
719 	status = usb_submit_urb(purb, GFP_ATOMIC);
720 	if (status) {
721 		rtw_sctx_done_err(&xmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
722 		DBG_88E("%s, status =%d\n", __func__, status);
723 		RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
724 			 ("%s(): usb_submit_urb, status =%x\n",
725 			  __func__, status));
726 
727 		switch (status) {
728 		case -ENODEV:
729 			padapter->bDriverStopped = true;
730 			break;
731 		default:
732 			break;
733 		}
734 		goto exit;
735 	}
736 
737 	ret = _SUCCESS;
738 
739 /*    We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */
740 
741 	RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("-%s\n", __func__));
742 
743 exit:
744 	if (ret != _SUCCESS)
745 		rtw_free_xmitbuf(pxmitpriv, xmitbuf);
746 	return ret;
747 }
748 
usb_write_port_cancel(struct adapter * padapter)749 void usb_write_port_cancel(struct adapter *padapter)
750 {
751 	int i, j;
752 	struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf;
753 
754 	DBG_88E("%s\n", __func__);
755 
756 	padapter->bWritePortCancel = true;
757 
758 	for (i = 0; i < NR_XMITBUFF; i++) {
759 		for (j = 0; j < 8; j++) {
760 			if (pxmitbuf->pxmit_urb[j])
761 				usb_kill_urb(pxmitbuf->pxmit_urb[j]);
762 		}
763 		pxmitbuf++;
764 	}
765 
766 	pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmit_extbuf;
767 	for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
768 		for (j = 0; j < 8; j++) {
769 			if (pxmitbuf->pxmit_urb[j])
770 				usb_kill_urb(pxmitbuf->pxmit_urb[j]);
771 		}
772 		pxmitbuf++;
773 	}
774 }
775 
rtl8188eu_recv_tasklet(struct tasklet_struct * t)776 void rtl8188eu_recv_tasklet(struct tasklet_struct *t)
777 {
778 	struct sk_buff *pskb;
779 	struct adapter *adapt = from_tasklet(adapt, t, recvpriv.recv_tasklet);
780 	struct recv_priv *precvpriv = &adapt->recvpriv;
781 
782 	while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
783 		if ((adapt->bDriverStopped) || (adapt->bSurpriseRemoved)) {
784 			DBG_88E("recv_tasklet => bDriverStopped or bSurpriseRemoved\n");
785 			dev_kfree_skb_any(pskb);
786 			break;
787 		}
788 		recvbuf2recvframe(adapt, pskb);
789 		skb_reset_tail_pointer(pskb);
790 		pskb->len = 0;
791 		skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
792 	}
793 }
794 
rtl8188eu_xmit_tasklet(struct tasklet_struct * t)795 void rtl8188eu_xmit_tasklet(struct tasklet_struct *t)
796 {
797 	struct adapter *adapt = from_tasklet(adapt, t, xmitpriv.xmit_tasklet);
798 	struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
799 
800 	if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY))
801 		return;
802 
803 	while (1) {
804 		if ((adapt->bDriverStopped) ||
805 		    (adapt->bSurpriseRemoved) ||
806 		    (adapt->bWritePortCancel)) {
807 			DBG_88E("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
808 			break;
809 		}
810 
811 		if (!rtl8188eu_xmitframe_complete(adapt, pxmitpriv))
812 			break;
813 	}
814 }
815