summaryrefslogtreecommitdiff
path: root/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/brcm80211/brcmfmac/bcmsdh.c')
-rw-r--r--drivers/staging/brcm80211/brcmfmac/bcmsdh.c631
1 files changed, 321 insertions, 310 deletions
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
index 3750fcf5a871..f4e72ed126b0 100644
--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
@@ -13,29 +13,59 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* ****************** BCMSDH Interface Functions *************************** */
+/* ****************** SDIO CARD Interface Functions **************************/
#include <linux/types.h>
#include <linux/netdevice.h>
+#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <bcmdefs.h>
-#include <bcmdevs.h>
-#include <bcmutils.h>
-#include <hndsoc.h>
-
-#include <bcmsdh.h> /* BRCM API for SDIO
- clients (such as wl, dhd) */
-#include <bcmsdbus.h> /* common SDIO/controller interface */
-#include <sbsdio.h> /* BRCM sdio device core */
-
-#include <sdio.h> /* sdio spec */
-#include "dngl_stats.h"
+#include <linux/sched.h>
+#include <linux/completion.h>
+
+#include <defs.h>
+#include <brcm_hw_ids.h>
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+#include <soc.h>
#include "dhd.h"
+#include "dhd_bus.h"
+#include "sdio_host.h"
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
-const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
-struct bcmsdh_info {
+#define BRCMF_SD_ERROR_VAL 0x0001 /* Error */
+#define BRCMF_SD_INFO_VAL 0x0002 /* Info */
+
+
+#ifdef BCMDBG
+#define BRCMF_SD_ERROR(x) \
+ do { \
+ if ((brcmf_sdio_msglevel & BRCMF_SD_ERROR_VAL) && \
+ net_ratelimit()) \
+ printk x; \
+ } while (0)
+#define BRCMF_SD_INFO(x) \
+ do { \
+ if ((brcmf_sdio_msglevel & BRCMF_SD_INFO_VAL) && \
+ net_ratelimit()) \
+ printk x; \
+ } while (0)
+#else /* BCMDBG */
+#define BRCMF_SD_ERROR(x)
+#define BRCMF_SD_INFO(x)
+#endif /* BCMDBG */
+
+/* debugging macros */
+#define SDLX_MSG(x)
+
+#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */
+#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */
+#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */
+
+#define SDIOH_DATA_PIO 0 /* PIO mode */
+#define SDIOH_DATA_DMA 1 /* DMA mode */
+
+struct brcmf_sdio_card {
bool init_success; /* underlying driver successfully attached */
void *sdioh; /* handler for sdioh */
u32 vendevid; /* Target Vendor and Device ID on SD bus */
@@ -43,282 +73,232 @@ struct bcmsdh_info {
reg_read/reg_write call */
u32 sbwad; /* Save backplane window address */
};
+
+/**
+ * SDIO Host Controller info
+ */
+struct sdio_hc {
+ struct sdio_hc *next;
+ struct device *dev; /* platform device handle */
+ void *regs; /* SDIO Host Controller address */
+ struct brcmf_sdio_card *card;
+ void *ch;
+ unsigned int oob_irq;
+ unsigned long oob_flags; /* OOB Host specifiction
+ as edge and etc */
+ bool oob_irq_registered;
+};
+
/* local copy of bcm sd handler */
-bcmsdh_info_t *l_bcmsdh;
+static struct brcmf_sdio_card *l_card;
-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
-extern int sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
+const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL;
-void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
-{
- sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
-}
-#endif
+static struct sdio_hc *sdhcinfo;
+
+/* driver info, initialized when brcmf_sdio_register is called */
+static struct brcmf_sdioh_driver drvinfo = { NULL, NULL };
+
+/* Module parameters specific to each host-controller driver */
+
+module_param(sd_msglevel, uint, 0);
-bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq)
+extern uint sd_f2_blocksize;
+module_param(sd_f2_blocksize, int, 0);
+
+/* forward declarations */
+int brcmf_sdio_probe(struct device *dev);
+EXPORT_SYMBOL(brcmf_sdio_probe);
+
+int brcmf_sdio_remove(struct device *dev);
+EXPORT_SYMBOL(brcmf_sdio_remove);
+
+struct brcmf_sdio_card*
+brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq)
{
- bcmsdh_info_t *bcmsdh;
+ struct brcmf_sdio_card *card;
- bcmsdh = kzalloc(sizeof(bcmsdh_info_t), GFP_ATOMIC);
- if (bcmsdh == NULL) {
- BCMSDH_ERROR(("bcmsdh_attach: out of memory"));
+ card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC);
+ if (card == NULL) {
+ BRCMF_SD_ERROR(("sdcard_attach: out of memory"));
return NULL;
}
/* save the handler locally */
- l_bcmsdh = bcmsdh;
+ l_card = card;
- bcmsdh->sdioh = sdioh_attach(cfghdl, irq);
- if (!bcmsdh->sdioh) {
- bcmsdh_detach(bcmsdh);
+ card->sdioh = brcmf_sdioh_attach(cfghdl, irq);
+ if (!card->sdioh) {
+ brcmf_sdcard_detach(card);
return NULL;
}
- bcmsdh->init_success = true;
+ card->init_success = true;
- *regsva = (u32 *) SI_ENUM_BASE;
+ *regsva = SI_ENUM_BASE;
/* Report the BAR, to fix if needed */
- bcmsdh->sbwad = SI_ENUM_BASE;
- return bcmsdh;
+ card->sbwad = SI_ENUM_BASE;
+ return card;
}
-int bcmsdh_detach(void *sdh)
+int brcmf_sdcard_detach(struct brcmf_sdio_card *card)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
-
- if (bcmsdh != NULL) {
- if (bcmsdh->sdioh) {
- sdioh_detach(bcmsdh->sdioh);
- bcmsdh->sdioh = NULL;
+ if (card != NULL) {
+ if (card->sdioh) {
+ brcmf_sdioh_detach(card->sdioh);
+ card->sdioh = NULL;
}
- kfree(bcmsdh);
+ kfree(card);
}
- l_bcmsdh = NULL;
+ l_card = NULL;
return 0;
}
int
-bcmsdh_iovar_op(void *sdh, const char *name,
+brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
void *params, int plen, void *arg, int len, bool set)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
-}
-
-bool bcmsdh_intr_query(void *sdh)
-{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
- bool on;
-
- ASSERT(bcmsdh);
- status = sdioh_interrupt_query(bcmsdh->sdioh, &on);
- if (SDIOH_API_SUCCESS(status))
- return false;
- else
- return on;
-}
-
-int bcmsdh_intr_enable(void *sdh)
-{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
- ASSERT(bcmsdh);
-
- status = sdioh_interrupt_set(bcmsdh->sdioh, true);
- return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg,
+ len, set);
}
-int bcmsdh_intr_disable(void *sdh)
+int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
- ASSERT(bcmsdh);
-
- status = sdioh_interrupt_set(bcmsdh->sdioh, false);
- return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ return brcmf_sdioh_interrupt_set(card->sdioh, true);
}
-int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
- ASSERT(bcmsdh);
-
- status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
- return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ return brcmf_sdioh_interrupt_set(card->sdioh, false);
}
-int bcmsdh_intr_dereg(void *sdh)
+int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
+ void (*fn)(void *), void *argh)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
- ASSERT(bcmsdh);
-
- status = sdioh_interrupt_deregister(bcmsdh->sdioh);
- return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh);
}
-#if defined(DHD_DEBUG)
-bool bcmsdh_intr_pending(void *sdh)
+int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
-
- ASSERT(sdh);
- return sdioh_interrupt_pending(bcmsdh->sdioh);
+ return brcmf_sdioh_interrupt_deregister(card->sdioh);
}
-#endif
-int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
+ int *err)
{
- ASSERT(sdh);
-
- /* don't support yet */
- return -ENOTSUPP;
-}
-
-u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err)
-{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+ int status;
s32 retry = 0;
-#endif
u8 data = 0;
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
-
- ASSERT(bcmsdh->init_success);
+ if (!card)
+ card = l_card;
-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
do {
if (retry) /* wait for 1 ms till bus get settled down */
udelay(1000);
-#endif
status =
- sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr,
+ brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr,
(u8 *) &data);
-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
- } while (!SDIOH_API_SUCCESS(status)
+ } while (status != 0
&& (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
-#endif
if (err)
- *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+ *err = status;
- BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
+ BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
__func__, fnc_num, addr, data));
return data;
}
void
-bcmsdh_cfg_write(void *sdh, uint fnc_num, u32 addr, u8 data, int *err)
+brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
+ u8 data, int *err)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+ int status;
s32 retry = 0;
-#endif
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
+ if (!card)
+ card = l_card;
- ASSERT(bcmsdh->init_success);
-
-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
do {
if (retry) /* wait for 1 ms till bus get settled down */
udelay(1000);
-#endif
status =
- sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr,
+ brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr,
(u8 *) &data);
-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
- } while (!SDIOH_API_SUCCESS(status)
+ } while (status != 0
&& (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
-#endif
if (err)
- *err = SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ *err = status;
- BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
+ BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
__func__, fnc_num, addr, data));
}
-u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr, int *err)
+u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
+ u32 addr, int *err)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
+ int status;
u32 data = 0;
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
-
- ASSERT(bcmsdh->init_success);
+ if (!card)
+ card = l_card;
- status =
- sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ,
- fnc_num, addr, &data, 4);
+ status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
+ SDIOH_READ, fnc_num, addr, &data, 4);
if (err)
- *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+ *err = status;
- BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
+ BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
__func__, fnc_num, addr, data));
return data;
}
void
-bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr, u32 data,
- int *err)
+brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num,
+ u32 addr, u32 data, int *err)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
-
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
+ int status;
- ASSERT(bcmsdh->init_success);
+ if (!card)
+ card = l_card;
status =
- sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+ brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
SDIOH_WRITE, fnc_num, addr, &data, 4);
if (err)
- *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+ *err = status;
- BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
+ BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
__func__, fnc_num, addr, data));
}
-int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length)
+int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis,
+ uint length)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
+ int status;
u8 *tmp_buf, *tmp_ptr;
u8 *ptr;
bool ascii = func & ~0xf;
func &= 0x7;
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
+ if (!card)
+ card = l_card;
- ASSERT(bcmsdh->init_success);
- ASSERT(cis);
- ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
-
- status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length);
+ status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length);
if (ascii) {
/* Move binary bits to tmp and format them
into the provided buffer. */
tmp_buf = kmalloc(length, GFP_ATOMIC);
if (tmp_buf == NULL) {
- BCMSDH_ERROR(("%s: out of memory\n", __func__));
+ BRCMF_SD_ERROR(("%s: out of memory\n", __func__));
return -ENOMEM;
}
memcpy(tmp_buf, cis, length);
@@ -331,60 +311,60 @@ int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length)
kfree(tmp_buf);
}
- return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ return status;
}
-static int bcmsdhsdio_set_sbaddr_window(void *sdh, u32 address)
+static int
+brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address)
{
int err = 0;
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
+ brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
(address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
if (!err)
- bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
- (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
+ brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
+ SBSDIO_FUNC1_SBADDRMID,
+ (address >> 16) & SBSDIO_SBADDRMID_MASK,
+ &err);
if (!err)
- bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
- (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
- &err);
+ brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
+ SBSDIO_FUNC1_SBADDRHIGH,
+ (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
+ &err);
return err;
}
-u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size)
+u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
+ int status;
u32 word = 0;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
- BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
-
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
+ BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
- ASSERT(bcmsdh->init_success);
+ if (!card)
+ card = l_card;
- if (bar0 != bcmsdh->sbwad) {
- if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))
+ if (bar0 != card->sbwad) {
+ if (brcmf_sdcard_set_sbaddr_window(card, bar0))
return 0xFFFFFFFF;
- bcmsdh->sbwad = bar0;
+ card->sbwad = bar0;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
if (size == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
- status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+ status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
- bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+ card->regfail = (status != 0);
- BCMSDH_INFO(("u32data = 0x%x\n", word));
+ BRCMF_SD_INFO(("u32data = 0x%x\n", word));
/* if ok, return appropriately masked word */
- if (SDIOH_API_SUCCESS(status)) {
+ if (status == 0) {
switch (size) {
case sizeof(u8):
return word & 0xff;
@@ -393,90 +373,86 @@ u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size)
case sizeof(u32):
return word;
default:
- bcmsdh->regfail = true;
+ card->regfail = true;
}
}
/* otherwise, bad sdio access or invalid size */
- BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
+ BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
addr, size));
return 0xFFFFFFFF;
}
-u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data)
+u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
+ u32 data)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
+ int status;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
- BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
+ BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
__func__, addr, size * 8, data));
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
-
- ASSERT(bcmsdh->init_success);
+ if (!card)
+ card = l_card;
- if (bar0 != bcmsdh->sbwad) {
- err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+ if (bar0 != card->sbwad) {
+ err = brcmf_sdcard_set_sbaddr_window(card, bar0);
if (err)
return err;
- bcmsdh->sbwad = bar0;
+ card->sbwad = bar0;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
if (size == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
status =
- sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+ brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
- bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+ card->regfail = (status != 0);
- if (SDIOH_API_SUCCESS(status))
+ if (status == 0)
return 0;
- BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
+ BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
__func__, data, addr, size));
return 0xFFFFFFFF;
}
-bool bcmsdh_regfail(void *sdh)
+bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card)
{
- return ((bcmsdh_info_t *) sdh)->regfail;
+ return card->regfail;
}
int
-bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
- u8 *buf, uint nbytes, struct sk_buff *pkt,
- bcmsdh_cmplt_fn_t complete, void *handle)
-{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
+brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
+ uint flags,
+ u8 *buf, uint nbytes, struct sk_buff *pkt,
+ void (*complete)(void *handle, int status,
+ bool sync_waiting),
+ void *handle)
+{
+ int status;
uint incr_fix;
uint width;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
- ASSERT(bcmsdh);
- ASSERT(bcmsdh->init_success);
-
- BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+ BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
__func__, fn, addr, nbytes));
/* Async not implemented yet */
- ASSERT(!(flags & SDIO_REQ_ASYNC));
if (flags & SDIO_REQ_ASYNC)
return -ENOTSUPP;
- if (bar0 != bcmsdh->sbwad) {
- err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+ if (bar0 != card->sbwad) {
+ err = brcmf_sdcard_set_sbaddr_window(card, bar0);
if (err)
return err;
- bcmsdh->sbwad = bar0;
+ card->sbwad = bar0;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
@@ -486,42 +462,37 @@ bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
if (width == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
- status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
- SDIOH_READ, fn, addr, width, nbytes, buf,
- pkt);
+ status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
+ incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
- return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ return status;
}
int
-bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
- u8 *buf, uint nbytes, void *pkt,
- bcmsdh_cmplt_fn_t complete, void *handle)
+brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
+ uint flags, u8 *buf, uint nbytes, void *pkt,
+ void (*complete)(void *handle, int status,
+ bool sync_waiting),
+ void *handle)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
uint incr_fix;
uint width;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
- ASSERT(bcmsdh);
- ASSERT(bcmsdh->init_success);
-
- BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+ BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
__func__, fn, addr, nbytes));
/* Async not implemented yet */
- ASSERT(!(flags & SDIO_REQ_ASYNC));
if (flags & SDIO_REQ_ASYNC)
return -ENOTSUPP;
- if (bar0 != bcmsdh->sbwad) {
- err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+ if (bar0 != card->sbwad) {
+ err = brcmf_sdcard_set_sbaddr_window(card, bar0);
if (err)
return err;
- bcmsdh->sbwad = bar0;
+ card->sbwad = bar0;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
@@ -531,101 +502,141 @@ bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
if (width == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
- status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
- SDIOH_WRITE, fn, addr, width, nbytes, buf,
- pkt);
-
- return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
+ incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
}
-int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes)
+int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
+ u8 *buf, uint nbytes)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- SDIOH_API_RC status;
-
- ASSERT(bcmsdh);
- ASSERT(bcmsdh->init_success);
- ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
-
addr &= SBSDIO_SB_OFT_ADDR_MASK;
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
- status =
- sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC,
- (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
- addr, 4, nbytes, buf, NULL);
-
- return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+ return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
+ SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
+ addr, 4, nbytes, buf, NULL);
}
-int bcmsdh_abort(void *sdh, uint fn)
+int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
-
- return sdioh_abort(bcmsdh->sdioh, fn);
+ return brcmf_sdioh_abort(card->sdioh, fn);
}
-int bcmsdh_start(void *sdh, int stage)
+int brcmf_sdcard_query_device(struct brcmf_sdio_card *card)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
-
- return sdioh_start(bcmsdh->sdioh, stage);
+ card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
+ return card->vendevid;
}
-int bcmsdh_stop(void *sdh)
+u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+ if (!card)
+ card = l_card;
- return sdioh_stop(bcmsdh->sdioh);
+ return card->sbwad;
}
-int bcmsdh_query_device(void *sdh)
+int brcmf_sdio_probe(struct device *dev)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
- bcmsdh->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
- return bcmsdh->vendevid;
-}
+ struct sdio_hc *sdhc = NULL;
+ u32 regs = 0;
+ struct brcmf_sdio_card *card = NULL;
+ int irq = 0;
+ u32 vendevid;
+ unsigned long irq_flags = 0;
-uint bcmsdh_query_iofnum(void *sdh)
-{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+ /* allocate SDIO Host Controller state info */
+ sdhc = kzalloc(sizeof(struct sdio_hc), GFP_ATOMIC);
+ if (!sdhc) {
+ SDLX_MSG(("%s: out of memory\n", __func__));
+ goto err;
+ }
+ sdhc->dev = (void *)dev;
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
+ card = brcmf_sdcard_attach((void *)0, &regs, irq);
+ if (!card) {
+ SDLX_MSG(("%s: attach failed\n", __func__));
+ goto err;
+ }
- return sdioh_query_iofnum(bcmsdh->sdioh);
-}
+ sdhc->card = card;
+ sdhc->oob_irq = irq;
+ sdhc->oob_flags = irq_flags;
+ sdhc->oob_irq_registered = false; /* to make sure.. */
+
+ /* chain SDIO Host Controller info together */
+ sdhc->next = sdhcinfo;
+ sdhcinfo = sdhc;
+ /* Read the vendor/device ID from the CIS */
+ vendevid = brcmf_sdcard_query_device(card);
+
+ /* try to attach to the target device */
+ sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
+ 0, 0, 0, 0, regs, card);
+ if (!sdhc->ch) {
+ SDLX_MSG(("%s: device attach failed\n", __func__));
+ goto err;
+ }
-int bcmsdh_reset(bcmsdh_info_t *sdh)
-{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+ return 0;
- return sdioh_sdio_reset(bcmsdh->sdioh);
-}
+ /* error handling */
+err:
+ if (sdhc) {
+ if (sdhc->card)
+ brcmf_sdcard_detach(sdhc->card);
+ kfree(sdhc);
+ }
-void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh)
-{
- ASSERT(sdh);
- return sdh->sdioh;
+ return -ENODEV;
}
-/* Function to pass device-status bits to DHD. */
-u32 bcmsdh_get_dstatus(void *sdh)
+int brcmf_sdio_remove(struct device *dev)
{
+ struct sdio_hc *sdhc, *prev;
+
+ sdhc = sdhcinfo;
+ drvinfo.detach(sdhc->ch);
+ brcmf_sdcard_detach(sdhc->card);
+ /* find the SDIO Host Controller state for this pdev
+ and take it out from the list */
+ for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
+ if (sdhc->dev == (void *)dev) {
+ if (prev)
+ prev->next = sdhc->next;
+ else
+ sdhcinfo = NULL;
+ break;
+ }
+ prev = sdhc;
+ }
+ if (!sdhc) {
+ SDLX_MSG(("%s: failed\n", __func__));
+ return 0;
+ }
+
+ /* release SDIO Host Controller info */
+ kfree(sdhc);
return 0;
}
-u32 bcmsdh_cur_sbwad(void *sdh)
+int brcmf_sdio_register(struct brcmf_sdioh_driver *driver)
{
- bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+ drvinfo = *driver;
- if (!bcmsdh)
- bcmsdh = l_bcmsdh;
+ SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
+ return brcmf_sdio_function_init();
+}
- return bcmsdh->sbwad;
+void brcmf_sdio_unregister(void)
+{
+ brcmf_sdio_function_cleanup();
}
-void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev)
+void brcmf_sdio_wdtmr_enable(bool enable)
{
- return;
+ if (enable)
+ brcmf_sdbrcm_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms);
+ else
+ brcmf_sdbrcm_wd_timer(sdhcinfo->ch, 0);
}