1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3 
4 #include "../include/osdep_service.h"
5 #include "../include/drv_types.h"
6 #include "../include/osdep_intf.h"
7 #include "../include/usb_ops.h"
8 #include "../include/recv_osdep.h"
9 #include "../include/rtl8188e_hal.h"
10 
usb_read(struct intf_hdl * intf,u16 value,void * data,u8 size)11 static int usb_read(struct intf_hdl *intf, u16 value, void *data, u8 size)
12 {
13 	struct adapter *adapt = intf->padapter;
14 	struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt);
15 	struct usb_device *udev = dvobjpriv->pusbdev;
16 	int status;
17 	u8 io_buf[4];
18 
19 	if (adapt->bSurpriseRemoved)
20 		return -EPERM;
21 
22 	status = usb_control_msg_recv(udev, 0, REALTEK_USB_VENQT_CMD_REQ,
23 				      REALTEK_USB_VENQT_READ, value,
24 				      REALTEK_USB_VENQT_CMD_IDX, io_buf,
25 				      size, RTW_USB_CONTROL_MSG_TIMEOUT,
26 				      GFP_KERNEL);
27 
28 	if (status == -ESHUTDOWN ||
29 	    status == -ENODEV ||
30 	    status == -ENOENT) {
31 		/*
32 		 * device or controller has been disabled due to
33 		 * some problem that could not be worked around,
34 		 * device or bus doesn’t exist, endpoint does not
35 		 * exist or is not enabled.
36 		 */
37 		adapt->bSurpriseRemoved = true;
38 		return status;
39 	}
40 
41 	if (status < 0) {
42 		if (rtw_inc_and_chk_continual_urb_error(dvobjpriv))
43 			adapt->bSurpriseRemoved = true;
44 
45 		return status;
46 	}
47 
48 	rtw_reset_continual_urb_error(dvobjpriv);
49 	memcpy(data, io_buf, size);
50 
51 	return status;
52 }
53 
usb_write(struct intf_hdl * intf,u16 value,void * data,u8 size)54 static int usb_write(struct intf_hdl *intf, u16 value, void *data, u8 size)
55 {
56 	struct adapter *adapt = intf->padapter;
57 	struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt);
58 	struct usb_device *udev = dvobjpriv->pusbdev;
59 	int status;
60 	u8 io_buf[VENDOR_CMD_MAX_DATA_LEN];
61 
62 	if (adapt->bSurpriseRemoved)
63 		return -EPERM;
64 
65 	memcpy(io_buf, data, size);
66 	status = usb_control_msg_send(udev, 0, REALTEK_USB_VENQT_CMD_REQ,
67 				      REALTEK_USB_VENQT_WRITE, value,
68 				      REALTEK_USB_VENQT_CMD_IDX, io_buf,
69 				      size, RTW_USB_CONTROL_MSG_TIMEOUT,
70 				      GFP_KERNEL);
71 
72 	if (status == -ESHUTDOWN ||
73 	    status == -ENODEV ||
74 	    status == -ENOENT) {
75 		/*
76 		 * device or controller has been disabled due to
77 		 * some problem that could not be worked around,
78 		 * device or bus doesn’t exist, endpoint does not
79 		 * exist or is not enabled.
80 		 */
81 		adapt->bSurpriseRemoved = true;
82 		return status;
83 	}
84 
85 	if (status < 0) {
86 		if (rtw_inc_and_chk_continual_urb_error(dvobjpriv))
87 			adapt->bSurpriseRemoved = true;
88 
89 		return status;
90 	}
91 
92 	rtw_reset_continual_urb_error(dvobjpriv);
93 
94 	return status;
95 }
96 
rtw_read8(struct adapter * adapter,u32 addr,u8 * data)97 int __must_check rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
98 {
99 	struct io_priv *io_priv = &adapter->iopriv;
100 	struct intf_hdl *intf = &io_priv->intf;
101 	u16 value = addr & 0xffff;
102 
103 	return usb_read(intf, value, data, 1);
104 }
105 
rtw_read16(struct adapter * adapter,u32 addr,u16 * data)106 int __must_check rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
107 {
108 	struct io_priv *io_priv = &adapter->iopriv;
109 	struct intf_hdl *intf = &io_priv->intf;
110 	u16 value = addr & 0xffff;
111 	__le16 le_data;
112 	int res;
113 
114 	res = usb_read(intf, value, &le_data, 2);
115 	if (res)
116 		return res;
117 
118 	*data = le16_to_cpu(le_data);
119 
120 	return 0;
121 }
122 
rtw_read32(struct adapter * adapter,u32 addr,u32 * data)123 int __must_check rtw_read32(struct adapter *adapter, u32 addr, u32 *data)
124 {
125 	struct io_priv *io_priv = &adapter->iopriv;
126 	struct intf_hdl *intf = &io_priv->intf;
127 	u16 value = addr & 0xffff;
128 	__le32 le_data;
129 	int res;
130 
131 	res = usb_read(intf, value, &le_data, 4);
132 	if (res)
133 		return res;
134 
135 	*data = le32_to_cpu(le_data);
136 
137 	return 0;
138 }
139 
rtw_write8(struct adapter * adapter,u32 addr,u8 val)140 int rtw_write8(struct adapter *adapter, u32 addr, u8 val)
141 {
142 	struct io_priv *io_priv = &adapter->iopriv;
143 	struct intf_hdl *intf = &io_priv->intf;
144 	u16 value = addr & 0xffff;
145 	int ret;
146 
147 	ret = usb_write(intf, value, &val, 1);
148 
149 	return RTW_STATUS_CODE(ret);
150 }
151 
rtw_write16(struct adapter * adapter,u32 addr,u16 val)152 int rtw_write16(struct adapter *adapter, u32 addr, u16 val)
153 {
154 	struct io_priv *io_priv = &adapter->iopriv;
155 	struct intf_hdl *intf = &io_priv->intf;
156 	u16 value = addr & 0xffff;
157 	__le16 data = cpu_to_le16(val);
158 	int ret;
159 
160 	ret = usb_write(intf, value, &data, 2);
161 
162 	return RTW_STATUS_CODE(ret);
163 }
164 
rtw_write32(struct adapter * adapter,u32 addr,u32 val)165 int rtw_write32(struct adapter *adapter, u32 addr, u32 val)
166 {
167 	struct io_priv *io_priv = &adapter->iopriv;
168 	struct intf_hdl *intf = &io_priv->intf;
169 	u16 value = addr & 0xffff;
170 	__le32 data = cpu_to_le32(val);
171 	int ret;
172 
173 	ret = usb_write(intf, value, &data, 4);
174 
175 	return RTW_STATUS_CODE(ret);
176 }
177 
rtw_writeN(struct adapter * adapter,u32 addr,u32 length,u8 * data)178 int rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *data)
179 {
180 	struct io_priv *io_priv = &adapter->iopriv;
181 	struct intf_hdl *intf = &io_priv->intf;
182 	u16 value = addr & 0xffff;
183 	int ret;
184 
185 	if (length > VENDOR_CMD_MAX_DATA_LEN)
186 		return _FAIL;
187 
188 	ret = usb_write(intf, value, data, length);
189 
190 	return RTW_STATUS_CODE(ret);
191 }
192 
recvbuf2recvframe(struct adapter * adapt,struct sk_buff * pskb)193 static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
194 {
195 	u8	*pbuf;
196 	u8	shift_sz = 0;
197 	u16	pkt_cnt;
198 	u32	pkt_offset, skb_len, alloc_sz;
199 	s32	transfer_len;
200 	struct recv_stat	*prxstat;
201 	struct phy_stat	*pphy_status = NULL;
202 	struct sk_buff *pkt_copy = NULL;
203 	struct recv_frame	*precvframe = NULL;
204 	struct rx_pkt_attrib	*pattrib = NULL;
205 	struct hal_data_8188e *haldata = &adapt->haldata;
206 	struct recv_priv	*precvpriv = &adapt->recvpriv;
207 	struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
208 
209 	transfer_len = (s32)pskb->len;
210 	pbuf = pskb->data;
211 
212 	prxstat = (struct recv_stat *)pbuf;
213 	pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
214 
215 	do {
216 		prxstat = (struct recv_stat *)pbuf;
217 
218 		precvframe = rtw_alloc_recvframe(pfree_recv_queue);
219 		if (!precvframe)
220 			goto _exit_recvbuf2recvframe;
221 
222 		INIT_LIST_HEAD(&precvframe->list);
223 		precvframe->precvbuf = NULL;	/* can't access the precvbuf for new arch. */
224 		precvframe->len = 0;
225 
226 		update_recvframe_attrib_88e(precvframe, prxstat);
227 
228 		pattrib = &precvframe->attrib;
229 
230 		if ((pattrib->crc_err) || (pattrib->icv_err)) {
231 			rtw_free_recvframe(precvframe, pfree_recv_queue);
232 			goto _exit_recvbuf2recvframe;
233 		}
234 
235 		if ((pattrib->physt) && (pattrib->pkt_rpt_type == NORMAL_RX))
236 			pphy_status = (struct phy_stat *)(pbuf + RXDESC_OFFSET);
237 
238 		pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
239 
240 		if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) {
241 			rtw_free_recvframe(precvframe, pfree_recv_queue);
242 			goto _exit_recvbuf2recvframe;
243 		}
244 
245 		/*	Modified by Albert 20101213 */
246 		/*	For 8 bytes IP header alignment. */
247 		if (pattrib->qos)	/*	Qos data, wireless lan header length is 26 */
248 			shift_sz = 6;
249 		else
250 			shift_sz = 0;
251 
252 		skb_len = pattrib->pkt_len;
253 
254 		/*  for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */
255 		/*  modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */
256 		if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
257 			if (skb_len <= 1650)
258 				alloc_sz = 1664;
259 			else
260 				alloc_sz = skb_len + 14;
261 		} else {
262 			alloc_sz = skb_len;
263 			/*	6 is for IP header 8 bytes alignment in QoS packet case. */
264 			/*	8 is for skb->data 4 bytes alignment. */
265 			alloc_sz += 14;
266 		}
267 
268 		pkt_copy = netdev_alloc_skb(adapt->pnetdev, alloc_sz);
269 		if (pkt_copy) {
270 			precvframe->pkt = pkt_copy;
271 			precvframe->rx_head = pkt_copy->data;
272 			precvframe->rx_end = pkt_copy->data + alloc_sz;
273 			skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */
274 			skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */
275 			memcpy(pkt_copy->data, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
276 			precvframe->rx_tail = pkt_copy->data;
277 			precvframe->rx_data = pkt_copy->data;
278 		} else {
279 			if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
280 				rtw_free_recvframe(precvframe, pfree_recv_queue);
281 				goto _exit_recvbuf2recvframe;
282 			}
283 			precvframe->pkt = skb_clone(pskb, GFP_ATOMIC);
284 			if (precvframe->pkt) {
285 				precvframe->rx_tail = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE;
286 				precvframe->rx_head = precvframe->rx_tail;
287 				precvframe->rx_data = precvframe->rx_tail;
288 				precvframe->rx_end =  pbuf + pattrib->drvinfo_sz + RXDESC_SIZE + alloc_sz;
289 			} else {
290 				rtw_free_recvframe(precvframe, pfree_recv_queue);
291 				goto _exit_recvbuf2recvframe;
292 			}
293 		}
294 
295 		recvframe_put(precvframe, skb_len);
296 
297 		pkt_offset = (u16)round_up(pkt_offset, 128);
298 
299 		if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */
300 			if (pattrib->physt)
301 				update_recvframe_phyinfo_88e(precvframe, (struct phy_stat *)pphy_status);
302 			rtw_recv_entry(precvframe);
303 		} else {
304 			/* enqueue recvframe to txrtp queue */
305 			if (pattrib->pkt_rpt_type == TX_REPORT1) {
306 				/* CCX-TXRPT ack for xmit mgmt frames. */
307 				handle_txrpt_ccx_88e(adapt, precvframe->rx_data);
308 			} else if (pattrib->pkt_rpt_type == TX_REPORT2) {
309 				ODM_RA_TxRPT2Handle_8188E(
310 							&haldata->odmpriv,
311 							precvframe->rx_data,
312 							pattrib->pkt_len,
313 							pattrib->MacIDValidEntry[0],
314 							pattrib->MacIDValidEntry[1]
315 							);
316 			}
317 			rtw_free_recvframe(precvframe, pfree_recv_queue);
318 		}
319 		pkt_cnt--;
320 		transfer_len -= pkt_offset;
321 		pbuf += pkt_offset;
322 		precvframe = NULL;
323 		pkt_copy = NULL;
324 
325 		if (transfer_len > 0 && pkt_cnt == 0)
326 			pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
327 
328 	} while ((transfer_len > 0) && (pkt_cnt > 0));
329 
330 _exit_recvbuf2recvframe:
331 
332 	return _SUCCESS;
333 }
334 
rtl8188eu_recv_tasklet(unsigned long priv)335 void rtl8188eu_recv_tasklet(unsigned long priv)
336 {
337 	struct sk_buff *pskb;
338 	struct adapter *adapt = (struct adapter *)priv;
339 	struct recv_priv *precvpriv = &adapt->recvpriv;
340 
341 	while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
342 		if ((adapt->bDriverStopped) || (adapt->bSurpriseRemoved)) {
343 			dev_kfree_skb_any(pskb);
344 			break;
345 		}
346 		recvbuf2recvframe(adapt, pskb);
347 		skb_reset_tail_pointer(pskb);
348 		pskb->len = 0;
349 		skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
350 	}
351 }
352 
usb_read_port_complete(struct urb * purb,struct pt_regs * regs)353 static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
354 {
355 	struct recv_buf	*precvbuf = (struct recv_buf *)purb->context;
356 	struct adapter	*adapt = (struct adapter *)precvbuf->adapter;
357 	struct recv_priv *precvpriv = &adapt->recvpriv;
358 
359 	precvpriv->rx_pending_cnt--;
360 
361 	if (adapt->bSurpriseRemoved || adapt->bDriverStopped || adapt->bReadPortCancel) {
362 		precvbuf->reuse = true;
363 		return;
364 	}
365 
366 	if (purb->status == 0) { /* SUCCESS */
367 		if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) {
368 			precvbuf->reuse = true;
369 			rtw_read_port(adapt, (unsigned char *)precvbuf);
370 		} else {
371 			rtw_reset_continual_urb_error(adapter_to_dvobj(adapt));
372 
373 			skb_put(precvbuf->pskb, purb->actual_length);
374 			skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
375 
376 			if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1)
377 				tasklet_schedule(&precvpriv->recv_tasklet);
378 
379 			precvbuf->pskb = NULL;
380 			precvbuf->reuse = false;
381 			rtw_read_port(adapt, (unsigned char *)precvbuf);
382 		}
383 	} else {
384 		skb_put(precvbuf->pskb, purb->actual_length);
385 		precvbuf->pskb = NULL;
386 
387 		if (rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(adapt)))
388 			adapt->bSurpriseRemoved = true;
389 
390 		switch (purb->status) {
391 		case -EINVAL:
392 		case -EPIPE:
393 		case -ENODEV:
394 		case -ESHUTDOWN:
395 		case -ENOENT:
396 			adapt->bDriverStopped = true;
397 			break;
398 		case -EPROTO:
399 		case -EOVERFLOW:
400 			precvbuf->reuse = true;
401 			rtw_read_port(adapt, (unsigned char *)precvbuf);
402 			break;
403 		case -EINPROGRESS:
404 			break;
405 		default:
406 			break;
407 		}
408 	}
409 }
410 
rtw_read_port(struct adapter * adapter,u8 * rmem)411 u32 rtw_read_port(struct adapter *adapter, u8 *rmem)
412 {
413 	struct urb *purb = NULL;
414 	struct recv_buf	*precvbuf = (struct recv_buf *)rmem;
415 	struct dvobj_priv	*pdvobj = adapter_to_dvobj(adapter);
416 	struct recv_priv	*precvpriv = &adapter->recvpriv;
417 	struct usb_device	*pusbd = pdvobj->pusbdev;
418 	int err;
419 	unsigned int pipe;
420 	size_t tmpaddr = 0;
421 	size_t alignment = 0;
422 	u32 ret = _SUCCESS;
423 
424 	if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
425 		return _FAIL;
426 
427 	if (!precvbuf)
428 		return _FAIL;
429 
430 	if (!precvbuf->reuse || !precvbuf->pskb) {
431 		precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
432 		if (precvbuf->pskb)
433 			precvbuf->reuse = true;
434 	}
435 
436 	/* re-assign for linux based on skb */
437 	if (!precvbuf->reuse || !precvbuf->pskb) {
438 		precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
439 		if (!precvbuf->pskb)
440 			return _FAIL;
441 
442 		tmpaddr = (size_t)precvbuf->pskb->data;
443 		alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
444 		skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
445 	} else { /* reuse skb */
446 		precvbuf->reuse = false;
447 	}
448 
449 	precvpriv->rx_pending_cnt++;
450 
451 	purb = precvbuf->purb;
452 
453 	/* translate DMA FIFO addr to pipehandle */
454 	pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe);
455 
456 	usb_fill_bulk_urb(purb, pusbd, pipe,
457 			  precvbuf->pskb->data,
458 			  MAX_RECVBUF_SZ,
459 			  usb_read_port_complete,
460 			  precvbuf);/* context is precvbuf */
461 
462 	err = usb_submit_urb(purb, GFP_ATOMIC);
463 	if ((err) && (err != (-EPERM)))
464 		ret = _FAIL;
465 
466 	return ret;
467 }
468 
rtl8188eu_xmit_tasklet(unsigned long priv)469 void rtl8188eu_xmit_tasklet(unsigned long priv)
470 {
471 	int ret = false;
472 	struct adapter *adapt = (struct adapter *)priv;
473 	struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
474 
475 	if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY))
476 		return;
477 
478 	while (1) {
479 		if ((adapt->bDriverStopped) ||
480 		    (adapt->bSurpriseRemoved) ||
481 		    (adapt->bWritePortCancel))
482 			break;
483 
484 		ret = rtl8188eu_xmitframe_complete(adapt, pxmitpriv, NULL);
485 
486 		if (!ret)
487 			break;
488 	}
489 }
490