| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- /******************************************************************************
- *
- * Copyright(c) 2015 - 2017 Realtek Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- *****************************************************************************/
- #define _RTW_SDIO_C_
- #include <drv_types.h> /* struct dvobj_priv and etc. */
- #include <drv_types_sdio.h> /* RTW_SDIO_ADDR_CMD52_GEN */
- /*
- * Description:
- * Use SDIO cmd52 or cmd53 to read/write data
- *
- * Parameters:
- * d pointer of device object(struct dvobj_priv)
- * addr SDIO address, 17 bits
- * buf buffer for I/O
- * len length
- * write 0:read, 1:write
- * cmd52 0:cmd52, 1:cmd53
- *
- * Return:
- * _SUCCESS I/O ok.
- * _FAIL I/O fail.
- */
- static u8 sdio_io(struct dvobj_priv *d, u32 addr, void *buf, size_t len, u8 write, u8 cmd52)
- {
- u32 addr_drv; /* address with driver defined bit */
- int err;
- u8 retry = 0;
- u8 stop_retry = _FALSE; /* flag for stopping retry or not */
- if (rtw_is_surprise_removed(dvobj_get_primary_adapter(d))) {
- RTW_ERR("%s: bSurpriseRemoved, skip %s 0x%05x, %zu bytes\n",
- __FUNCTION__, write?"write":"read", addr, len);
- return _FAIL;
- }
- addr_drv = addr;
- if (cmd52)
- addr_drv = RTW_SDIO_ADDR_CMD52_GEN(addr_drv);
- do {
- if (write)
- err = d->intf_ops->write(d, addr_drv, buf, len, 0);
- else
- err = d->intf_ops->read(d, addr_drv, buf, len, 0);
- if (!err) {
- if (retry) {
- RTW_INFO("%s: Retry %s OK! addr=0x%05x %zu bytes, retry=%u,%u\n",
- __FUNCTION__, write?"write":"read",
- addr, len, retry, ATOMIC_READ(&d->continual_io_error));
- RTW_INFO_DUMP("Data: ", buf, len);
- }
- rtw_reset_continual_io_error(d);
- break;
- }
- RTW_ERR("%s: %s FAIL! error(%d) addr=0x%05x %zu bytes, retry=%u,%u\n",
- __FUNCTION__, write?"write":"read", err, addr, len,
- retry, ATOMIC_READ(&d->continual_io_error));
- retry++;
- stop_retry = rtw_inc_and_chk_continual_io_error(d);
- if ((err == -1) || (stop_retry == _TRUE) || (retry > SD_IO_TRY_CNT)) {
- /* critical error, unrecoverable */
- RTW_ERR("%s: Fatal error! Set surprise remove flag ON! (retry=%u,%u)\n",
- __FUNCTION__, retry, ATOMIC_READ(&d->continual_io_error));
- rtw_set_surprise_removed(dvobj_get_primary_adapter(d));
- return _FAIL;
- }
- /* WLAN IOREG or SDIO Local */
- if ((addr & 0x10000) || !(addr & 0xE000)) {
- RTW_WARN("%s: Retry %s addr=0x%05x %zu bytes, retry=%u,%u\n",
- __FUNCTION__, write?"write":"read", addr, len,
- retry, ATOMIC_READ(&d->continual_io_error));
- continue;
- }
- return _FAIL;
- } while (1);
- return _SUCCESS;
- }
- u8 rtw_sdio_read_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
- {
- return sdio_io(d, addr, buf, len, 0, 1);
- }
- u8 rtw_sdio_read_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
- {
- return sdio_io(d, addr, buf, len, 0, 0);
- }
- u8 rtw_sdio_write_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
- {
- return sdio_io(d, addr, buf, len, 1, 1);
- }
- u8 rtw_sdio_write_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
- {
- return sdio_io(d, addr, buf, len, 1, 0);
- }
- u8 rtw_sdio_f0_read(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
- {
- int err;
- u8 ret;
- ret = _SUCCESS;
- addr = RTW_SDIO_ADDR_F0_GEN(addr);
- err = d->intf_ops->read(d, addr, buf, len, 0);
- if (err)
- ret = _FAIL;
- return ret;
- }
|