1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * usb_ops_linux.c 4 * 5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. 6 * Linux device driver for RTL8192SU 7 * 8 * Modifications for inclusion into the Linux staging tree are 9 * Copyright(c) 2010 Larry Finger. All rights reserved. 10 * 11 * Contact information: 12 * WLAN FAE <wlanfae@realtek.com> 13 * Larry Finger <Larry.Finger@lwfinger.net> 14 * 15 ******************************************************************************/ 16 17 #define _HCI_OPS_OS_C_ 18 19 #include <linux/usb.h> 20 21 #include "osdep_service.h" 22 #include "drv_types.h" 23 #include "osdep_intf.h" 24 #include "usb_ops.h" 25 26 #define RTL871X_VENQT_READ 0xc0 27 #define RTL871X_VENQT_WRITE 0x40 28 29 struct zero_bulkout_context { 30 void *pbuf; 31 void *purb; 32 void *pirp; 33 void *padapter; 34 }; 35 36 uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv) 37 { 38 pintfpriv->piorw_urb = usb_alloc_urb(0, GFP_ATOMIC); 39 if (!pintfpriv->piorw_urb) 40 return _FAIL; 41 init_completion(&pintfpriv->io_retevt_comp); 42 return _SUCCESS; 43 } 44 45 void r8712_usb_unload_intf_priv(struct intf_priv *pintfpriv) 46 { 47 if (pintfpriv->piorw_urb) { 48 usb_kill_urb(pintfpriv->piorw_urb); 49 usb_free_urb(pintfpriv->piorw_urb); 50 } 51 } 52 53 static unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr) 54 { 55 unsigned int pipe = 0; 56 struct usb_device *pusbd = pdvobj->pusbdev; 57 58 if (pdvobj->nr_endpoint == 11) { 59 switch (addr) { 60 case RTL8712_DMA_BKQ: 61 pipe = usb_sndbulkpipe(pusbd, 0x07); 62 break; 63 case RTL8712_DMA_BEQ: 64 pipe = usb_sndbulkpipe(pusbd, 0x06); 65 break; 66 case RTL8712_DMA_VIQ: 67 pipe = usb_sndbulkpipe(pusbd, 0x05); 68 break; 69 case RTL8712_DMA_VOQ: 70 pipe = usb_sndbulkpipe(pusbd, 0x04); 71 break; 72 case RTL8712_DMA_BCNQ: 73 pipe = usb_sndbulkpipe(pusbd, 0x0a); 74 break; 75 case RTL8712_DMA_BMCQ: /* HI Queue */ 76 pipe = usb_sndbulkpipe(pusbd, 0x0b); 77 break; 78 case RTL8712_DMA_MGTQ: 79 pipe = usb_sndbulkpipe(pusbd, 0x0c); 80 break; 81 case RTL8712_DMA_RX0FF: 82 pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ 83 break; 84 case RTL8712_DMA_C2HCMD: 85 pipe = usb_rcvbulkpipe(pusbd, 0x09); /* in */ 86 break; 87 case RTL8712_DMA_H2CCMD: 88 pipe = usb_sndbulkpipe(pusbd, 0x0d); 89 break; 90 } 91 } else if (pdvobj->nr_endpoint == 6) { 92 switch (addr) { 93 case RTL8712_DMA_BKQ: 94 pipe = usb_sndbulkpipe(pusbd, 0x07); 95 break; 96 case RTL8712_DMA_BEQ: 97 pipe = usb_sndbulkpipe(pusbd, 0x06); 98 break; 99 case RTL8712_DMA_VIQ: 100 pipe = usb_sndbulkpipe(pusbd, 0x05); 101 break; 102 case RTL8712_DMA_VOQ: 103 pipe = usb_sndbulkpipe(pusbd, 0x04); 104 break; 105 case RTL8712_DMA_RX0FF: 106 case RTL8712_DMA_C2HCMD: 107 pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ 108 break; 109 case RTL8712_DMA_H2CCMD: 110 case RTL8712_DMA_BCNQ: 111 case RTL8712_DMA_BMCQ: 112 case RTL8712_DMA_MGTQ: 113 pipe = usb_sndbulkpipe(pusbd, 0x0d); 114 break; 115 } 116 } else if (pdvobj->nr_endpoint == 4) { 117 switch (addr) { 118 case RTL8712_DMA_BEQ: 119 pipe = usb_sndbulkpipe(pusbd, 0x06); 120 break; 121 case RTL8712_DMA_VOQ: 122 pipe = usb_sndbulkpipe(pusbd, 0x04); 123 break; 124 case RTL8712_DMA_RX0FF: 125 case RTL8712_DMA_C2HCMD: 126 pipe = usb_rcvbulkpipe(pusbd, 0x03); /* in */ 127 break; 128 case RTL8712_DMA_H2CCMD: 129 case RTL8712_DMA_BCNQ: 130 case RTL8712_DMA_BMCQ: 131 case RTL8712_DMA_MGTQ: 132 pipe = usb_sndbulkpipe(pusbd, 0x0d); 133 break; 134 } 135 } else { 136 pipe = 0; 137 } 138 return pipe; 139 } 140 141 static void usb_write_mem_complete(struct urb *purb) 142 { 143 struct io_queue *pio_q = (struct io_queue *)purb->context; 144 struct intf_hdl *pintf = &(pio_q->intf); 145 struct intf_priv *pintfpriv = pintf->pintfpriv; 146 struct _adapter *padapter = (struct _adapter *)pintf->adapter; 147 148 if (purb->status != 0) { 149 if (purb->status == (-ESHUTDOWN)) 150 padapter->driver_stopped = true; 151 else 152 padapter->surprise_removed = true; 153 } 154 complete(&pintfpriv->io_retevt_comp); 155 } 156 157 void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) 158 { 159 unsigned int pipe; 160 struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter; 161 struct intf_priv *pintfpriv = pintfhdl->pintfpriv; 162 struct io_queue *pio_queue = padapter->pio_queue; 163 struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev; 164 struct usb_device *pusbd = pdvobj->pusbdev; 165 struct urb *piorw_urb = pintfpriv->piorw_urb; 166 167 if ((padapter->driver_stopped) || (padapter->surprise_removed) || 168 (padapter->pwrctrlpriv.pnp_bstop_trx)) 169 return; 170 /* translate DMA FIFO addr to pipehandle */ 171 pipe = ffaddr2pipehdl(pdvobj, addr); 172 if (pipe == 0) 173 return; 174 usb_fill_bulk_urb(piorw_urb, pusbd, pipe, 175 wmem, cnt, usb_write_mem_complete, 176 pio_queue); 177 usb_submit_urb(piorw_urb, GFP_ATOMIC); 178 wait_for_completion_interruptible(&pintfpriv->io_retevt_comp); 179 } 180 181 static void r8712_usb_read_port_complete(struct urb *purb) 182 { 183 uint isevt; 184 __le32 *pbuf; 185 struct recv_buf *precvbuf = (struct recv_buf *)purb->context; 186 struct _adapter *padapter = (struct _adapter *)precvbuf->adapter; 187 struct recv_priv *precvpriv = &padapter->recvpriv; 188 189 if (padapter->surprise_removed || padapter->driver_stopped) 190 return; 191 if (purb->status == 0) { /* SUCCESS */ 192 if ((purb->actual_length > (MAX_RECVBUF_SZ)) || 193 (purb->actual_length < RXDESC_SIZE)) { 194 r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, 195 (unsigned char *)precvbuf); 196 } else { 197 _pkt *pskb = precvbuf->pskb; 198 199 precvbuf->transfer_len = purb->actual_length; 200 pbuf = (__le32 *)precvbuf->pbuf; 201 isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff; 202 if ((isevt & 0x1ff) == 0x1ff) { 203 r8712_rxcmd_event_hdl(padapter, pbuf); 204 skb_queue_tail(&precvpriv->rx_skb_queue, pskb); 205 r8712_read_port(padapter, precvpriv->ff_hwaddr, 206 0, (unsigned char *)precvbuf); 207 } else { 208 skb_put(pskb, purb->actual_length); 209 skb_queue_tail(&precvpriv->rx_skb_queue, pskb); 210 tasklet_hi_schedule(&precvpriv->recv_tasklet); 211 r8712_read_port(padapter, precvpriv->ff_hwaddr, 212 0, (unsigned char *)precvbuf); 213 } 214 } 215 } else { 216 switch (purb->status) { 217 case -EINVAL: 218 case -EPIPE: 219 case -ENODEV: 220 case -ESHUTDOWN: 221 padapter->driver_stopped = true; 222 break; 223 case -ENOENT: 224 if (!padapter->suspended) { 225 padapter->driver_stopped = true; 226 break; 227 } 228 fallthrough; 229 case -EPROTO: 230 r8712_read_port(padapter, precvpriv->ff_hwaddr, 0, 231 (unsigned char *)precvbuf); 232 break; 233 case -EINPROGRESS: 234 netdev_err(padapter->pnetdev, "ERROR: URB IS IN PROGRESS!\n"); 235 break; 236 default: 237 break; 238 } 239 } 240 } 241 242 u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) 243 { 244 unsigned int pipe; 245 int err; 246 u32 tmpaddr = 0; 247 int alignment = 0; 248 u32 ret = _SUCCESS; 249 struct urb *purb = NULL; 250 struct recv_buf *precvbuf = (struct recv_buf *)rmem; 251 struct intf_priv *pintfpriv = pintfhdl->pintfpriv; 252 struct dvobj_priv *pdvobj = (struct dvobj_priv *)pintfpriv->intf_dev; 253 struct _adapter *adapter = pdvobj->padapter; 254 struct recv_priv *precvpriv = &adapter->recvpriv; 255 struct usb_device *pusbd = pdvobj->pusbdev; 256 257 if (adapter->driver_stopped || adapter->surprise_removed || 258 adapter->pwrctrlpriv.pnp_bstop_trx || !precvbuf) 259 return _FAIL; 260 r8712_init_recvbuf(adapter, precvbuf); 261 /* Try to use skb from the free queue */ 262 precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); 263 264 if (!precvbuf->pskb) { 265 precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, 266 MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); 267 if (!precvbuf->pskb) 268 return _FAIL; 269 tmpaddr = (addr_t)precvbuf->pskb->data; 270 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1); 271 skb_reserve(precvbuf->pskb, 272 (RECVBUFF_ALIGN_SZ - alignment)); 273 precvbuf->phead = precvbuf->pskb->head; 274 precvbuf->pdata = precvbuf->pskb->data; 275 precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); 276 precvbuf->pend = skb_end_pointer(precvbuf->pskb); 277 precvbuf->pbuf = precvbuf->pskb->data; 278 } else { /* skb is reused */ 279 precvbuf->phead = precvbuf->pskb->head; 280 precvbuf->pdata = precvbuf->pskb->data; 281 precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); 282 precvbuf->pend = skb_end_pointer(precvbuf->pskb); 283 precvbuf->pbuf = precvbuf->pskb->data; 284 } 285 purb = precvbuf->purb; 286 /* translate DMA FIFO addr to pipehandle */ 287 pipe = ffaddr2pipehdl(pdvobj, addr); 288 usb_fill_bulk_urb(purb, pusbd, pipe, 289 precvbuf->pbuf, MAX_RECVBUF_SZ, 290 r8712_usb_read_port_complete, 291 precvbuf); 292 err = usb_submit_urb(purb, GFP_ATOMIC); 293 if ((err) && (err != (-EPERM))) 294 ret = _FAIL; 295 return ret; 296 } 297 298 void r8712_usb_read_port_cancel(struct _adapter *padapter) 299 { 300 int i; 301 struct recv_buf *precvbuf; 302 303 precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf; 304 for (i = 0; i < NR_RECVBUFF; i++) { 305 if (precvbuf->purb) 306 usb_kill_urb(precvbuf->purb); 307 precvbuf++; 308 } 309 } 310 311 void r8712_xmit_bh(struct tasklet_struct *t) 312 { 313 int ret = false; 314 struct _adapter *padapter = from_tasklet(padapter, t, 315 xmitpriv.xmit_tasklet); 316 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 317 318 if (padapter->driver_stopped || 319 padapter->surprise_removed) { 320 netdev_err(padapter->pnetdev, "xmit_bh => driver_stopped or surprise_removed\n"); 321 return; 322 } 323 ret = r8712_xmitframe_complete(padapter, pxmitpriv, NULL); 324 if (!ret) 325 return; 326 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); 327 } 328 329 static void usb_write_port_complete(struct urb *purb) 330 { 331 int i; 332 struct xmit_frame *pxmitframe = (struct xmit_frame *)purb->context; 333 struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; 334 struct _adapter *padapter = pxmitframe->padapter; 335 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 336 struct pkt_attrib *pattrib = &pxmitframe->attrib; 337 338 switch (pattrib->priority) { 339 case 1: 340 case 2: 341 pxmitpriv->bkq_cnt--; 342 break; 343 case 4: 344 case 5: 345 pxmitpriv->viq_cnt--; 346 break; 347 case 6: 348 case 7: 349 pxmitpriv->voq_cnt--; 350 break; 351 case 0: 352 case 3: 353 default: 354 pxmitpriv->beq_cnt--; 355 break; 356 } 357 pxmitpriv->txirp_cnt--; 358 for (i = 0; i < 8; i++) { 359 if (purb == pxmitframe->pxmit_urb[i]) { 360 pxmitframe->bpending[i] = false; 361 break; 362 } 363 } 364 if (padapter->surprise_removed) 365 return; 366 switch (purb->status) { 367 case 0: 368 break; 369 default: 370 netdev_warn(padapter->pnetdev, 371 "r8712u: pipe error: (%d)\n", purb->status); 372 break; 373 } 374 /* not to consider tx fragment */ 375 r8712_free_xmitframe_ex(pxmitpriv, pxmitframe); 376 r8712_free_xmitbuf(pxmitpriv, pxmitbuf); 377 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); 378 } 379 380 u32 r8712_usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem) 381 { 382 unsigned long irqL; 383 int i, status; 384 unsigned int pipe; 385 u32 ret, bwritezero; 386 struct urb *purb = NULL; 387 struct _adapter *padapter = (struct _adapter *)pintfhdl->adapter; 388 struct dvobj_priv *pdvobj = &padapter->dvobjpriv; 389 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 390 struct xmit_frame *pxmitframe = (struct xmit_frame *)wmem; 391 struct usb_device *pusbd = pdvobj->pusbdev; 392 struct pkt_attrib *pattrib = &pxmitframe->attrib; 393 394 if ((padapter->driver_stopped) || (padapter->surprise_removed) || 395 (padapter->pwrctrlpriv.pnp_bstop_trx)) 396 return _FAIL; 397 for (i = 0; i < 8; i++) { 398 if (!pxmitframe->bpending[i]) { 399 spin_lock_irqsave(&pxmitpriv->lock, irqL); 400 pxmitpriv->txirp_cnt++; 401 pxmitframe->bpending[i] = true; 402 switch (pattrib->priority) { 403 case 1: 404 case 2: 405 pxmitpriv->bkq_cnt++; 406 break; 407 case 4: 408 case 5: 409 pxmitpriv->viq_cnt++; 410 break; 411 case 6: 412 case 7: 413 pxmitpriv->voq_cnt++; 414 break; 415 case 0: 416 case 3: 417 default: 418 pxmitpriv->beq_cnt++; 419 break; 420 } 421 spin_unlock_irqrestore(&pxmitpriv->lock, irqL); 422 pxmitframe->sz[i] = (u16)cnt; 423 purb = pxmitframe->pxmit_urb[i]; 424 break; 425 } 426 } 427 bwritezero = false; 428 if (pdvobj->ishighspeed) { 429 if (cnt > 0 && cnt % 512 == 0) 430 bwritezero = true; 431 } else { 432 if (cnt > 0 && cnt % 64 == 0) 433 bwritezero = true; 434 } 435 /* translate DMA FIFO addr to pipehandle */ 436 pipe = ffaddr2pipehdl(pdvobj, addr); 437 if (pxmitpriv->free_xmitbuf_cnt % NR_XMITBUFF == 0) 438 purb->transfer_flags &= (~URB_NO_INTERRUPT); 439 else 440 purb->transfer_flags |= URB_NO_INTERRUPT; 441 if (bwritezero) 442 cnt += 8; 443 usb_fill_bulk_urb(purb, pusbd, pipe, 444 pxmitframe->mem_addr, 445 cnt, usb_write_port_complete, 446 pxmitframe); /* context is xmit_frame */ 447 status = usb_submit_urb(purb, GFP_ATOMIC); 448 if (!status) 449 ret = _SUCCESS; 450 else 451 ret = _FAIL; 452 return ret; 453 } 454 455 void r8712_usb_write_port_cancel(struct _adapter *padapter) 456 { 457 int i, j; 458 struct xmit_buf *pxmitbuf = (struct xmit_buf *) 459 padapter->xmitpriv.pxmitbuf; 460 461 for (i = 0; i < NR_XMITBUFF; i++) { 462 for (j = 0; j < 8; j++) { 463 if (pxmitbuf->pxmit_urb[j]) 464 usb_kill_urb(pxmitbuf->pxmit_urb[j]); 465 } 466 pxmitbuf++; 467 } 468 } 469 470 int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value, 471 u16 index, void *pdata, u16 len, u8 requesttype) 472 { 473 unsigned int pipe; 474 int status; 475 u8 reqtype; 476 struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *) 477 pintfpriv->intf_dev; 478 struct usb_device *udev = pdvobjpriv->pusbdev; 479 /* For mstar platform, mstar suggests the address for USB IO 480 * should be 16 bytes alignment. Trying to fix it here. 481 */ 482 u8 *palloc_buf, *pIo_buf; 483 484 palloc_buf = kmalloc((u32)len + 16, GFP_ATOMIC); 485 if (!palloc_buf) 486 return -ENOMEM; 487 pIo_buf = palloc_buf + 16 - ((addr_t)(palloc_buf) & 0x0f); 488 if (requesttype == 0x01) { 489 pipe = usb_rcvctrlpipe(udev, 0); /* read_in */ 490 reqtype = RTL871X_VENQT_READ; 491 } else { 492 pipe = usb_sndctrlpipe(udev, 0); /* write_out */ 493 reqtype = RTL871X_VENQT_WRITE; 494 memcpy(pIo_buf, pdata, len); 495 } 496 status = usb_control_msg(udev, pipe, request, reqtype, value, index, 497 pIo_buf, len, 500); 498 if (status < 0) 499 goto free; 500 if (status != len) { 501 status = -EREMOTEIO; 502 goto free; 503 } 504 /* Success this control transfer. */ 505 if (requesttype == 0x01) { 506 /* For Control read transfer, we have to copy the read 507 * data from pIo_buf to pdata. 508 */ 509 memcpy(pdata, pIo_buf, status); 510 } 511 512 free: 513 kfree(palloc_buf); 514 return status; 515 } 516