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__, err, addr+i, pdata[i]); 160 break; 161 } 162 } 163 return err; 164 } 165 166 /* 167 * Return: 168 *0 Success 169 *others Fail 170 */ 171 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 172 { 173 struct adapter *padapter; 174 struct dvobj_priv *psdiodev; 175 struct sdio_data *psdio; 176 177 int err = 0; 178 struct sdio_func *func; 179 bool claim_needed; 180 181 padapter = pintfhdl->padapter; 182 psdiodev = pintfhdl->pintf_dev; 183 psdio = &psdiodev->intf_data; 184 185 if (padapter->bSurpriseRemoved) { 186 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 187 return err; 188 } 189 190 func = psdio->func; 191 claim_needed = rtw_sdio_claim_host_needed(func); 192 193 if (claim_needed) 194 sdio_claim_host(func); 195 err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata); 196 if (claim_needed) 197 sdio_release_host(func); 198 return err; 199 } 200 201 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err) 202 { 203 struct adapter *padapter; 204 struct dvobj_priv *psdiodev; 205 struct sdio_data *psdio; 206 207 u8 v = 0; 208 struct sdio_func *func; 209 bool claim_needed; 210 211 padapter = pintfhdl->padapter; 212 psdiodev = pintfhdl->pintf_dev; 213 psdio = &psdiodev->intf_data; 214 215 if (padapter->bSurpriseRemoved) { 216 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 217 return v; 218 } 219 220 func = psdio->func; 221 claim_needed = rtw_sdio_claim_host_needed(func); 222 223 if (claim_needed) 224 sdio_claim_host(func); 225 v = sdio_readb(func, addr, err); 226 if (claim_needed) 227 sdio_release_host(func); 228 if (err && *err) 229 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr); 230 return v; 231 } 232 233 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err) 234 { 235 struct adapter *padapter; 236 struct dvobj_priv *psdiodev; 237 struct sdio_data *psdio; 238 u32 v = 0; 239 struct sdio_func *func; 240 bool claim_needed; 241 242 padapter = pintfhdl->padapter; 243 psdiodev = pintfhdl->pintf_dev; 244 psdio = &psdiodev->intf_data; 245 246 if (padapter->bSurpriseRemoved) { 247 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 248 return v; 249 } 250 251 func = psdio->func; 252 claim_needed = rtw_sdio_claim_host_needed(func); 253 254 if (claim_needed) 255 sdio_claim_host(func); 256 v = sdio_readl(func, addr, err); 257 if (claim_needed) 258 sdio_release_host(func); 259 260 if (err && *err) { 261 int i; 262 263 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x\n", __func__, *err, addr, v); 264 265 *err = 0; 266 for (i = 0; i < SD_IO_TRY_CNT; i++) { 267 if (claim_needed) sdio_claim_host(func); 268 v = sdio_readl(func, addr, err); 269 if (claim_needed) sdio_release_host(func); 270 271 if (*err == 0) { 272 rtw_reset_continual_io_error(psdiodev); 273 break; 274 } else { 275 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); 276 if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) { 277 padapter->bSurpriseRemoved = true; 278 } 279 280 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { 281 padapter->bSurpriseRemoved = true; 282 break; 283 } 284 } 285 } 286 287 if (i == SD_IO_TRY_CNT) 288 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); 289 else 290 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); 291 292 } 293 return v; 294 } 295 296 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err) 297 { 298 struct adapter *padapter; 299 struct dvobj_priv *psdiodev; 300 struct sdio_data *psdio; 301 struct sdio_func *func; 302 bool claim_needed; 303 304 padapter = pintfhdl->padapter; 305 psdiodev = pintfhdl->pintf_dev; 306 psdio = &psdiodev->intf_data; 307 308 if (padapter->bSurpriseRemoved) { 309 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 310 return; 311 } 312 313 func = psdio->func; 314 claim_needed = rtw_sdio_claim_host_needed(func); 315 316 if (claim_needed) 317 sdio_claim_host(func); 318 sdio_writeb(func, v, addr, err); 319 if (claim_needed) 320 sdio_release_host(func); 321 if (err && *err) 322 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, *err, addr, v); 323 } 324 325 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err) 326 { 327 struct adapter *padapter; 328 struct dvobj_priv *psdiodev; 329 struct sdio_data *psdio; 330 struct sdio_func *func; 331 bool claim_needed; 332 333 padapter = pintfhdl->padapter; 334 psdiodev = pintfhdl->pintf_dev; 335 psdio = &psdiodev->intf_data; 336 337 if (padapter->bSurpriseRemoved) { 338 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 339 return; 340 } 341 342 func = psdio->func; 343 claim_needed = rtw_sdio_claim_host_needed(func); 344 345 if (claim_needed) 346 sdio_claim_host(func); 347 sdio_writel(func, v, addr, err); 348 if (claim_needed) 349 sdio_release_host(func); 350 351 if (err && *err) { 352 int i; 353 354 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x\n", __func__, *err, addr, v); 355 356 *err = 0; 357 for (i = 0; i < SD_IO_TRY_CNT; i++) { 358 if (claim_needed) sdio_claim_host(func); 359 sdio_writel(func, v, addr, err); 360 if (claim_needed) sdio_release_host(func); 361 if (*err == 0) { 362 rtw_reset_continual_io_error(psdiodev); 363 break; 364 } else { 365 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i); 366 if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) { 367 padapter->bSurpriseRemoved = true; 368 } 369 370 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { 371 padapter->bSurpriseRemoved = true; 372 break; 373 } 374 } 375 } 376 377 if (i == SD_IO_TRY_CNT) 378 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i); 379 else 380 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i); 381 } 382 } 383 384 /* 385 * Use CMD53 to read data from SDIO device. 386 * This function MUST be called after sdio_claim_host() or 387 * in SDIO ISR(host had been claimed). 388 * 389 * Parameters: 390 *psdio pointer of SDIO_DATA 391 *addr address to read 392 *cnt amount to read 393 *pdata pointer to put data, this should be a "DMA:able scratch buffer"! 394 * 395 * Return: 396 *0 Success 397 *others Fail 398 */ 399 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 400 { 401 struct adapter *padapter; 402 struct dvobj_priv *psdiodev; 403 struct sdio_data *psdio; 404 405 int err = -EPERM; 406 struct sdio_func *func; 407 408 padapter = pintfhdl->padapter; 409 psdiodev = pintfhdl->pintf_dev; 410 psdio = &psdiodev->intf_data; 411 412 if (padapter->bSurpriseRemoved) { 413 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 414 return err; 415 } 416 417 func = psdio->func; 418 419 if (unlikely((cnt == 1) || (cnt == 2))) { 420 int i; 421 u8 *pbuf = pdata; 422 423 for (i = 0; i < cnt; i++) { 424 *(pbuf+i) = sdio_readb(func, addr+i, &err); 425 426 if (err) { 427 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr); 428 break; 429 } 430 } 431 return err; 432 } 433 434 err = sdio_memcpy_fromio(func, pdata, addr, cnt); 435 if (err) { 436 DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d\n", __func__, err, addr, cnt); 437 } 438 return err; 439 } 440 441 /* 442 * Use CMD53 to read data from SDIO device. 443 * 444 * Parameters: 445 *psdio pointer of SDIO_DATA 446 *addr address to read 447 *cnt amount to read 448 *pdata pointer to put data, this should be a "DMA:able scratch buffer"! 449 * 450 * Return: 451 *0 Success 452 *others Fail 453 */ 454 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 455 { 456 struct adapter *padapter; 457 struct dvobj_priv *psdiodev; 458 struct sdio_data *psdio; 459 460 struct sdio_func *func; 461 bool claim_needed; 462 s32 err = -EPERM; 463 464 padapter = pintfhdl->padapter; 465 psdiodev = pintfhdl->pintf_dev; 466 psdio = &psdiodev->intf_data; 467 468 if (padapter->bSurpriseRemoved) { 469 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 470 return err; 471 } 472 func = psdio->func; 473 claim_needed = rtw_sdio_claim_host_needed(func); 474 475 if (claim_needed) 476 sdio_claim_host(func); 477 err = _sd_read(pintfhdl, addr, cnt, pdata); 478 if (claim_needed) 479 sdio_release_host(func); 480 return err; 481 } 482 483 /* 484 * Use CMD53 to write data to SDIO device. 485 * This function MUST be called after sdio_claim_host() or 486 * in SDIO ISR(host had been claimed). 487 * 488 * Parameters: 489 *psdio pointer of SDIO_DATA 490 *addr address to write 491 *cnt amount to write 492 *pdata data pointer, this should be a "DMA:able scratch buffer"! 493 * 494 * Return: 495 *0 Success 496 *others Fail 497 */ 498 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 499 { 500 struct adapter *padapter; 501 struct dvobj_priv *psdiodev; 502 struct sdio_data *psdio; 503 504 struct sdio_func *func; 505 u32 size; 506 s32 err = -EPERM; 507 508 padapter = pintfhdl->padapter; 509 psdiodev = pintfhdl->pintf_dev; 510 psdio = &psdiodev->intf_data; 511 512 if (padapter->bSurpriseRemoved) { 513 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 514 return err; 515 } 516 517 func = psdio->func; 518 /* size = sdio_align_size(func, cnt); */ 519 520 if (unlikely((cnt == 1) || (cnt == 2))) { 521 int i; 522 u8 *pbuf = pdata; 523 524 for (i = 0; i < cnt; i++) { 525 sdio_writeb(func, *(pbuf+i), addr+i, &err); 526 if (err) { 527 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, err, addr, *(pbuf+i)); 528 break; 529 } 530 } 531 532 return err; 533 } 534 535 size = cnt; 536 err = sdio_memcpy_toio(func, addr, pdata, size); 537 if (err) { 538 DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d(%d)\n", __func__, err, addr, cnt, size); 539 } 540 return err; 541 } 542 543 /* 544 * Use CMD53 to write data to SDIO device. 545 * 546 * Parameters: 547 * psdio pointer of SDIO_DATA 548 * addr address to write 549 * cnt amount to write 550 * pdata data pointer, this should be a "DMA:able scratch buffer"! 551 * 552 * Return: 553 * 0 Success 554 * others Fail 555 */ 556 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 557 { 558 struct adapter *padapter; 559 struct dvobj_priv *psdiodev; 560 struct sdio_data *psdio; 561 struct sdio_func *func; 562 bool claim_needed; 563 s32 err = -EPERM; 564 565 padapter = pintfhdl->padapter; 566 psdiodev = pintfhdl->pintf_dev; 567 psdio = &psdiodev->intf_data; 568 569 if (padapter->bSurpriseRemoved) { 570 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */ 571 return err; 572 } 573 574 func = psdio->func; 575 claim_needed = rtw_sdio_claim_host_needed(func); 576 577 if (claim_needed) 578 sdio_claim_host(func); 579 err = _sd_write(pintfhdl, addr, cnt, pdata); 580 if (claim_needed) 581 sdio_release_host(func); 582 return err; 583 } 584