1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 5 * 6 *******************************************************************************/ 7 #define _SDIO_OPS_LINUX_C_ 8 9 #include <drv_types.h> 10 #include <rtw_debug.h> 11 12 static bool rtw_sdio_claim_host_needed(struct sdio_func *func) 13 { 14 struct dvobj_priv *dvobj = sdio_get_drvdata(func); 15 struct sdio_data *sdio_data = &dvobj->intf_data; 16 17 if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current) 18 return false; 19 return true; 20 } 21 22 inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, void *thd_hdl) 23 { 24 struct sdio_data *sdio_data = &dvobj->intf_data; 25 26 sdio_data->sys_sdio_irq_thd = thd_hdl; 27 } 28 29 u8 sd_f0_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err) 30 { 31 struct adapter *padapter; 32 struct dvobj_priv *psdiodev; 33 struct sdio_data *psdio; 34 35 u8 v = 0; 36 struct sdio_func *func; 37 bool claim_needed; 38 39 padapter = pintfhdl->padapter; 40 psdiodev = pintfhdl->pintf_dev; 41 psdio = &psdiodev->intf_data; 42 43 if (padapter->bSurpriseRemoved) { 44 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 45 return v; 46 } 47 48 func = psdio->func; 49 claim_needed = rtw_sdio_claim_host_needed(func); 50 51 if (claim_needed) 52 sdio_claim_host(func); 53 v = sdio_f0_readb(func, addr, err); 54 if (claim_needed) 55 sdio_release_host(func); 56 if (err && *err) 57 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr); 58 return v; 59 } 60 61 /* 62 * Return: 63 *0 Success 64 *others Fail 65 */ 66 s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 67 { 68 struct adapter *padapter; 69 struct dvobj_priv *psdiodev; 70 struct sdio_data *psdio; 71 72 int err = 0, i; 73 struct sdio_func *func; 74 75 padapter = pintfhdl->padapter; 76 psdiodev = pintfhdl->pintf_dev; 77 psdio = &psdiodev->intf_data; 78 79 if (padapter->bSurpriseRemoved) { 80 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 81 return err; 82 } 83 84 func = psdio->func; 85 86 for (i = 0; i < cnt; i++) { 87 pdata[i] = sdio_readb(func, addr + i, &err); 88 if (err) { 89 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr + i); 90 break; 91 } 92 } 93 return err; 94 } 95 96 /* 97 * Return: 98 *0 Success 99 *others Fail 100 */ 101 s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 102 { 103 struct adapter *padapter; 104 struct dvobj_priv *psdiodev; 105 struct sdio_data *psdio; 106 107 int err = 0; 108 struct sdio_func *func; 109 bool claim_needed; 110 111 padapter = pintfhdl->padapter; 112 psdiodev = pintfhdl->pintf_dev; 113 psdio = &psdiodev->intf_data; 114 115 if (padapter->bSurpriseRemoved) { 116 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 117 return err; 118 } 119 120 func = psdio->func; 121 claim_needed = rtw_sdio_claim_host_needed(func); 122 123 if (claim_needed) 124 sdio_claim_host(func); 125 err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata); 126 if (claim_needed) 127 sdio_release_host(func); 128 return err; 129 } 130 131 /* 132 * Return: 133 *0 Success 134 *others Fail 135 */ 136 s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 137 { 138 struct adapter *padapter; 139 struct dvobj_priv *psdiodev; 140 struct sdio_data *psdio; 141 142 int err = 0, i; 143 struct sdio_func *func; 144 145 padapter = pintfhdl->padapter; 146 psdiodev = pintfhdl->pintf_dev; 147 psdio = &psdiodev->intf_data; 148 149 if (padapter->bSurpriseRemoved) { 150 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 151 return err; 152 } 153 154 func = psdio->func; 155 156 for (i = 0; i < cnt; i++) { 157 sdio_writeb(func, pdata[i], addr + i, &err); 158 if (err) { 159 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, 160 err, addr + i, pdata[i]); 161 break; 162 } 163 } 164 return err; 165 } 166 167 /* 168 * Return: 169 *0 Success 170 *others Fail 171 */ 172 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 173 { 174 struct adapter *padapter; 175 struct dvobj_priv *psdiodev; 176 struct sdio_data *psdio; 177 178 int err = 0; 179 struct sdio_func *func; 180 bool claim_needed; 181 182 padapter = pintfhdl->padapter; 183 psdiodev = pintfhdl->pintf_dev; 184 psdio = &psdiodev->intf_data; 185 186 if (padapter->bSurpriseRemoved) { 187 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 188 return err; 189 } 190 191 func = psdio->func; 192 claim_needed = rtw_sdio_claim_host_needed(func); 193 194 if (claim_needed) 195 sdio_claim_host(func); 196 err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata); 197 if (claim_needed) 198 sdio_release_host(func); 199 return err; 200 } 201 202 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err) 203 { 204 struct adapter *padapter; 205 struct dvobj_priv *psdiodev; 206 struct sdio_data *psdio; 207 208 u8 v = 0; 209 struct sdio_func *func; 210 bool claim_needed; 211 212 padapter = pintfhdl->padapter; 213 psdiodev = pintfhdl->pintf_dev; 214 psdio = &psdiodev->intf_data; 215 216 if (padapter->bSurpriseRemoved) { 217 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 218 return v; 219 } 220 221 func = psdio->func; 222 claim_needed = rtw_sdio_claim_host_needed(func); 223 224 if (claim_needed) 225 sdio_claim_host(func); 226 v = sdio_readb(func, addr, err); 227 if (claim_needed) 228 sdio_release_host(func); 229 if (err && *err) 230 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr); 231 return v; 232 } 233 234 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err) 235 { 236 struct adapter *padapter; 237 struct dvobj_priv *psdiodev; 238 struct sdio_data *psdio; 239 u32 v = 0; 240 struct sdio_func *func; 241 bool claim_needed; 242 243 padapter = pintfhdl->padapter; 244 psdiodev = pintfhdl->pintf_dev; 245 psdio = &psdiodev->intf_data; 246 247 if (padapter->bSurpriseRemoved) { 248 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 249 return v; 250 } 251 252 func = psdio->func; 253 claim_needed = rtw_sdio_claim_host_needed(func); 254 255 if (claim_needed) 256 sdio_claim_host(func); 257 v = sdio_readl(func, addr, err); 258 if (claim_needed) 259 sdio_release_host(func); 260 261 if (err && *err) { 262 int i; 263 264 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x\n", __func__, *err, addr, v); 265 266 *err = 0; 267 for (i = 0; i < SD_IO_TRY_CNT; i++) { 268 if (claim_needed) 269 sdio_claim_host(func); 270 v = sdio_readl(func, addr, err); 271 if (claim_needed) 272 sdio_release_host(func); 273 274 if (*err == 0) { 275 rtw_reset_continual_io_error(psdiodev); 276 break; 277 } else { 278 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); 279 if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) 280 padapter->bSurpriseRemoved = true; 281 282 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { 283 padapter->bSurpriseRemoved = true; 284 break; 285 } 286 } 287 } 288 289 if (i == SD_IO_TRY_CNT) 290 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); 291 else 292 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); 293 294 } 295 return v; 296 } 297 298 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err) 299 { 300 struct adapter *padapter; 301 struct dvobj_priv *psdiodev; 302 struct sdio_data *psdio; 303 struct sdio_func *func; 304 bool claim_needed; 305 306 padapter = pintfhdl->padapter; 307 psdiodev = pintfhdl->pintf_dev; 308 psdio = &psdiodev->intf_data; 309 310 if (padapter->bSurpriseRemoved) { 311 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 312 return; 313 } 314 315 func = psdio->func; 316 claim_needed = rtw_sdio_claim_host_needed(func); 317 318 if (claim_needed) 319 sdio_claim_host(func); 320 sdio_writeb(func, v, addr, err); 321 if (claim_needed) 322 sdio_release_host(func); 323 if (err && *err) 324 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, *err, addr, v); 325 } 326 327 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err) 328 { 329 struct adapter *padapter; 330 struct dvobj_priv *psdiodev; 331 struct sdio_data *psdio; 332 struct sdio_func *func; 333 bool claim_needed; 334 335 padapter = pintfhdl->padapter; 336 psdiodev = pintfhdl->pintf_dev; 337 psdio = &psdiodev->intf_data; 338 339 if (padapter->bSurpriseRemoved) { 340 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 341 return; 342 } 343 344 func = psdio->func; 345 claim_needed = rtw_sdio_claim_host_needed(func); 346 347 if (claim_needed) 348 sdio_claim_host(func); 349 sdio_writel(func, v, addr, err); 350 if (claim_needed) 351 sdio_release_host(func); 352 353 if (err && *err) { 354 int i; 355 356 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x\n", __func__, *err, addr, v); 357 358 *err = 0; 359 for (i = 0; i < SD_IO_TRY_CNT; i++) { 360 if (claim_needed) 361 sdio_claim_host(func); 362 sdio_writel(func, v, addr, err); 363 if (claim_needed) 364 sdio_release_host(func); 365 if (*err == 0) { 366 rtw_reset_continual_io_error(psdiodev); 367 break; 368 } else { 369 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); 370 if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) 371 padapter->bSurpriseRemoved = true; 372 373 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { 374 padapter->bSurpriseRemoved = true; 375 break; 376 } 377 } 378 } 379 380 if (i == SD_IO_TRY_CNT) 381 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i); 382 else 383 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i); 384 } 385 } 386 387 /* 388 * Use CMD53 to read data from SDIO device. 389 * This function MUST be called after sdio_claim_host() or 390 * in SDIO ISR(host had been claimed). 391 * 392 * Parameters: 393 *psdio pointer of SDIO_DATA 394 *addr address to read 395 *cnt amount to read 396 *pdata pointer to put data, this should be a "DMA:able scratch buffer"! 397 * 398 * Return: 399 *0 Success 400 *others Fail 401 */ 402 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 403 { 404 struct adapter *padapter; 405 struct dvobj_priv *psdiodev; 406 struct sdio_data *psdio; 407 408 int err = -EPERM; 409 struct sdio_func *func; 410 411 padapter = pintfhdl->padapter; 412 psdiodev = pintfhdl->pintf_dev; 413 psdio = &psdiodev->intf_data; 414 415 if (padapter->bSurpriseRemoved) { 416 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 417 return err; 418 } 419 420 func = psdio->func; 421 422 if (unlikely((cnt == 1) || (cnt == 2))) { 423 int i; 424 u8 *pbuf = pdata; 425 426 for (i = 0; i < cnt; i++) { 427 *(pbuf + i) = sdio_readb(func, addr + i, &err); 428 429 if (err) { 430 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr); 431 break; 432 } 433 } 434 return err; 435 } 436 437 err = sdio_memcpy_fromio(func, pdata, addr, cnt); 438 if (err) 439 DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d\n", __func__, err, addr, cnt); 440 441 return err; 442 } 443 444 /* 445 * Use CMD53 to read data from SDIO device. 446 * 447 * Parameters: 448 *psdio pointer of SDIO_DATA 449 *addr address to read 450 *cnt amount to read 451 *pdata pointer to put data, this should be a "DMA:able scratch buffer"! 452 * 453 * Return: 454 *0 Success 455 *others Fail 456 */ 457 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 458 { 459 struct adapter *padapter; 460 struct dvobj_priv *psdiodev; 461 struct sdio_data *psdio; 462 463 struct sdio_func *func; 464 bool claim_needed; 465 s32 err = -EPERM; 466 467 padapter = pintfhdl->padapter; 468 psdiodev = pintfhdl->pintf_dev; 469 psdio = &psdiodev->intf_data; 470 471 if (padapter->bSurpriseRemoved) { 472 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 473 return err; 474 } 475 func = psdio->func; 476 claim_needed = rtw_sdio_claim_host_needed(func); 477 478 if (claim_needed) 479 sdio_claim_host(func); 480 err = _sd_read(pintfhdl, addr, cnt, pdata); 481 if (claim_needed) 482 sdio_release_host(func); 483 return err; 484 } 485 486 /* 487 * Use CMD53 to write data to SDIO device. 488 * This function MUST be called after sdio_claim_host() or 489 * in SDIO ISR(host had been claimed). 490 * 491 * Parameters: 492 *psdio pointer of SDIO_DATA 493 *addr address to write 494 *cnt amount to write 495 *pdata data pointer, this should be a "DMA:able scratch buffer"! 496 * 497 * Return: 498 *0 Success 499 *others Fail 500 */ 501 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 502 { 503 struct adapter *padapter; 504 struct dvobj_priv *psdiodev; 505 struct sdio_data *psdio; 506 507 struct sdio_func *func; 508 u32 size; 509 s32 err = -EPERM; 510 511 padapter = pintfhdl->padapter; 512 psdiodev = pintfhdl->pintf_dev; 513 psdio = &psdiodev->intf_data; 514 515 if (padapter->bSurpriseRemoved) { 516 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 517 return err; 518 } 519 520 func = psdio->func; 521 /* size = sdio_align_size(func, cnt); */ 522 523 if (unlikely((cnt == 1) || (cnt == 2))) { 524 int i; 525 u8 *pbuf = pdata; 526 527 for (i = 0; i < cnt; i++) { 528 sdio_writeb(func, *(pbuf + i), addr + i, &err); 529 if (err) { 530 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", 531 __func__, err, addr, *(pbuf + i)); 532 break; 533 } 534 } 535 536 return err; 537 } 538 539 size = cnt; 540 err = sdio_memcpy_toio(func, addr, pdata, size); 541 if (err) 542 DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d(%d)\n", __func__, err, addr, cnt, size); 543 544 return err; 545 } 546 547 /* 548 * Use CMD53 to write data to SDIO device. 549 * 550 * Parameters: 551 * psdio pointer of SDIO_DATA 552 * addr address to write 553 * cnt amount to write 554 * pdata data pointer, this should be a "DMA:able scratch buffer"! 555 * 556 * Return: 557 * 0 Success 558 * others Fail 559 */ 560 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 561 { 562 struct adapter *padapter; 563 struct dvobj_priv *psdiodev; 564 struct sdio_data *psdio; 565 struct sdio_func *func; 566 bool claim_needed; 567 s32 err = -EPERM; 568 569 padapter = pintfhdl->padapter; 570 psdiodev = pintfhdl->pintf_dev; 571 psdio = &psdiodev->intf_data; 572 573 if (padapter->bSurpriseRemoved) { 574 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 575 return err; 576 } 577 578 func = psdio->func; 579 claim_needed = rtw_sdio_claim_host_needed(func); 580 581 if (claim_needed) 582 sdio_claim_host(func); 583 err = _sd_write(pintfhdl, addr, cnt, pdata); 584 if (claim_needed) 585 sdio_release_host(func); 586 return err; 587 } 588