rtw_sdio.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2015 - 2017 Realtek Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. *****************************************************************************/
  15. #define _RTW_SDIO_C_
  16. #include <drv_types.h> /* struct dvobj_priv and etc. */
  17. #include <drv_types_sdio.h> /* RTW_SDIO_ADDR_CMD52_GEN */
  18. /*
  19. * Description:
  20. * Use SDIO cmd52 or cmd53 to read/write data
  21. *
  22. * Parameters:
  23. * d pointer of device object(struct dvobj_priv)
  24. * addr SDIO address, 17 bits
  25. * buf buffer for I/O
  26. * len length
  27. * write 0:read, 1:write
  28. * cmd52 0:cmd52, 1:cmd53
  29. *
  30. * Return:
  31. * _SUCCESS I/O ok.
  32. * _FAIL I/O fail.
  33. */
  34. static u8 sdio_io(struct dvobj_priv *d, u32 addr, void *buf, size_t len, u8 write, u8 cmd52)
  35. {
  36. u32 addr_drv; /* address with driver defined bit */
  37. int err;
  38. u8 retry = 0;
  39. u8 stop_retry = _FALSE; /* flag for stopping retry or not */
  40. if (rtw_is_surprise_removed(dvobj_get_primary_adapter(d))) {
  41. RTW_ERR("%s: bSurpriseRemoved, skip %s 0x%05x, %zu bytes\n",
  42. __FUNCTION__, write?"write":"read", addr, len);
  43. return _FAIL;
  44. }
  45. addr_drv = addr;
  46. if (cmd52)
  47. addr_drv = RTW_SDIO_ADDR_CMD52_GEN(addr_drv);
  48. do {
  49. if (write)
  50. err = d->intf_ops->write(d, addr_drv, buf, len, 0);
  51. else
  52. err = d->intf_ops->read(d, addr_drv, buf, len, 0);
  53. if (!err) {
  54. if (retry) {
  55. RTW_INFO("%s: Retry %s OK! addr=0x%05x %zu bytes, retry=%u,%u\n",
  56. __FUNCTION__, write?"write":"read",
  57. addr, len, retry, ATOMIC_READ(&d->continual_io_error));
  58. RTW_INFO_DUMP("Data: ", buf, len);
  59. }
  60. rtw_reset_continual_io_error(d);
  61. break;
  62. }
  63. RTW_ERR("%s: %s FAIL! error(%d) addr=0x%05x %zu bytes, retry=%u,%u\n",
  64. __FUNCTION__, write?"write":"read", err, addr, len,
  65. retry, ATOMIC_READ(&d->continual_io_error));
  66. retry++;
  67. stop_retry = rtw_inc_and_chk_continual_io_error(d);
  68. if ((err == -1) || (stop_retry == _TRUE) || (retry > SD_IO_TRY_CNT)) {
  69. /* critical error, unrecoverable */
  70. RTW_ERR("%s: Fatal error! Set surprise remove flag ON! (retry=%u,%u)\n",
  71. __FUNCTION__, retry, ATOMIC_READ(&d->continual_io_error));
  72. rtw_set_surprise_removed(dvobj_get_primary_adapter(d));
  73. return _FAIL;
  74. }
  75. /* WLAN IOREG or SDIO Local */
  76. if ((addr & 0x10000) || !(addr & 0xE000)) {
  77. RTW_WARN("%s: Retry %s addr=0x%05x %zu bytes, retry=%u,%u\n",
  78. __FUNCTION__, write?"write":"read", addr, len,
  79. retry, ATOMIC_READ(&d->continual_io_error));
  80. continue;
  81. }
  82. return _FAIL;
  83. } while (1);
  84. return _SUCCESS;
  85. }
  86. u8 rtw_sdio_read_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
  87. {
  88. return sdio_io(d, addr, buf, len, 0, 1);
  89. }
  90. u8 rtw_sdio_read_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
  91. {
  92. return sdio_io(d, addr, buf, len, 0, 0);
  93. }
  94. u8 rtw_sdio_write_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
  95. {
  96. return sdio_io(d, addr, buf, len, 1, 1);
  97. }
  98. u8 rtw_sdio_write_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
  99. {
  100. return sdio_io(d, addr, buf, len, 1, 0);
  101. }
  102. u8 rtw_sdio_f0_read(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
  103. {
  104. int err;
  105. u8 ret;
  106. ret = _SUCCESS;
  107. addr = RTW_SDIO_ADDR_F0_GEN(addr);
  108. err = d->intf_ops->read(d, addr, buf, len, 0);
  109. if (err)
  110. ret = _FAIL;
  111. return ret;
  112. }