aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2013-03-15 12:54:01 -0700
committerZiyan <jaraidaniel@gmail.com>2016-05-01 23:35:14 +0200
commitfdc64453fdb3b6994b0e56fa542b8567bc24ba54 (patch)
tree7295d62f85aa21a88098edf037e16a577a2026e2 /drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
parentf2a2177f59124834879276a1aefcf47c68ec0416 (diff)
downloadkernel_samsung_tuna-fdc64453fdb3b6994b0e56fa542b8567bc24ba54.zip
kernel_samsung_tuna-fdc64453fdb3b6994b0e56fa542b8567bc24ba54.tar.gz
kernel_samsung_tuna-fdc64453fdb3b6994b0e56fa542b8567bc24ba54.tar.bz2
net: wireless: bcmdhd: Update to version 1.88.4
- Improve P2P concurrency - Re-arch proptxstatus code - Fix WMM (QoS) traffic differentiation test Change-Id: Id204048255a5ab41913da260adf9154a350f7a77 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c')
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c173
1 files changed, 73 insertions, 100 deletions
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
index 046bd02..ee818ab 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
@@ -1,7 +1,7 @@
/*
* BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
*
- * Copyright (C) 1999-2012, Broadcom Corporation
+ * Copyright (C) 1999-2013, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_sdmmc.c 379078 2013-01-16 00:41:36Z $
+ * $Id: bcmsdh_sdmmc.c 386902 2013-02-22 09:10:37Z $
*/
#include <typedefs.h>
@@ -76,6 +76,12 @@ uint sd_clock = 1; /* Default to SD Clock turned ON */
uint sd_hiok = FALSE; /* Don't use hi-speed mode by default */
uint sd_msglevel = 0x01;
uint sd_use_dma = TRUE;
+
+
+#ifndef CUSTOM_RXCHAIN
+#define CUSTOM_RXCHAIN 0
+#endif
+
DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait);
DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait);
DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait);
@@ -154,7 +160,7 @@ sdioh_attach(osl_t *osh, void *bar0, uint irq)
sd->sd_blockmode = TRUE;
sd->use_client_ints = TRUE;
sd->client_block_size[0] = 64;
- sd->use_rxchain = FALSE;
+ sd->use_rxchain = CUSTOM_RXCHAIN;
gInstance->sd = sd;
@@ -779,10 +785,11 @@ sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length)
extern SDIOH_API_RC
sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte)
{
- int err_ret;
+ int err_ret = 0;
#if defined(MMC_SDIO_ABORT)
int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT;
#endif
+
sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr));
DHD_PM_RESUME_WAIT(sdioh_request_byte_wait);
@@ -820,10 +827,10 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by
if (gInstance->func[func]) {
sdio_claim_host(gInstance->func[func]);
/*
- * this sdio_f0_writeb() can be replaced with
- * another api depending upon MMC driver change.
- * As of this time, this is temporaray one
- */
+ * this sdio_f0_writeb() can be replaced with
+ * another api depending upon MMC driver change.
+ * As of this time, this is temporaray one
+ */
sdio_writeb(gInstance->func[func],
*byte, regaddr, &err_ret);
sdio_release_host(gInstance->func[func]);
@@ -866,8 +873,11 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by
}
if (err_ret) {
- sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
- rw ? "Write" : "Read", func, regaddr, *byte, err_ret));
+ if ((regaddr == 0x1001F) && (err_ret == -110)) {
+ } else {
+ sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
+ rw ? "Write" : "Read", func, regaddr, *byte, err_ret));
+ }
}
return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
@@ -895,7 +905,7 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint add
/* Claim host controller */
sdio_claim_host(gInstance->func[func]);
- if(rw) { /* CMD53 Write */
+ if(rw) { /* CMD52 Write */
if (nbytes == 4) {
sdio_writel(gInstance->func[func], *word, addr, &err_ret);
} else if (nbytes == 2) {
@@ -923,10 +933,10 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint add
if (gInstance->func[0]) {
sdio_claim_host(gInstance->func[0]);
/*
- * this sdio_f0_writeb() can be replaced with another api
- * depending upon MMC driver change.
- * As of this time, this is temporaray one
- */
+ * this sdio_f0_writeb() can be replaced with another api
+ * depending upon MMC driver change.
+ * As of this time, this is temporaray one
+ */
sdio_writeb(gInstance->func[0],
func, SDIOD_CCCR_IOABORT, &err_ret);
sdio_release_host(gInstance->func[0]);
@@ -937,14 +947,15 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint add
if (err_ret)
#endif /* MMC_SDIO_ABORT */
{
- sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x\n",
- rw ? "Write" : "Read", err_ret));
+ sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x",
+ rw ? "Write" : "Read", err_ret));
}
}
return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
}
+
static SDIOH_API_RC
sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
uint addr, void *pkt)
@@ -952,7 +963,7 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
bool fifo = (fix_inc == SDIOH_DATA_FIX);
uint32 SGCount = 0;
int err_ret = 0;
- void *pnext, *pprev;
+ void *pnext;
uint ttl_len, dma_len, lft_len, xfred_len, pkt_len;
uint blk_num;
int blk_size;
@@ -967,18 +978,21 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
ttl_len = xfred_len = 0;
+
/* at least 4 bytes alignment of skb buff is guaranteed */
for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext))
ttl_len += PKTLEN(sd->osh, pnext);
blk_size = sd->client_block_size[func];
- if (!sd->use_rxchain || ttl_len <= blk_size) {
- blk_num = 0;
- dma_len = 0;
- } else {
+ if (((!write && sd->use_rxchain) ||
+ 0) && (ttl_len > blk_size)) {
blk_num = ttl_len / blk_size;
dma_len = blk_num * blk_size;
+ } else {
+ blk_num = 0;
+ dma_len = 0;
}
+
lft_len = ttl_len - dma_len;
sd_trace(("%s: %s %dB to func%d:%08x, %d blks with DMA, %dB leftover\n",
@@ -991,7 +1005,6 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
memset(&mmc_dat, 0, sizeof(struct mmc_data));
/* Set up DMA descriptors */
- pprev = pkt;
for (pnext = pkt;
pnext && dma_len;
pnext = PKTNEXT(sd->osh, pnext)) {
@@ -1045,12 +1058,8 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
__FUNCTION__,
write ? "write" : "read",
err_ret));
- sd_err(("%s:Disabling rxchain and fire it with PIO\n",
- __FUNCTION__));
- sd->use_rxchain = FALSE;
- pkt = pprev;
- lft_len = ttl_len;
- } else if (!fifo) {
+ }
+ if (!fifo) {
addr = addr + ttl_len - lft_len - dma_len;
}
}
@@ -1068,11 +1077,8 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
xfred_len = 0;
}
- /* Align Patch
- * read or small packet(ex:BDC header) skip 32 byte align
- * otherwise, padding DHD_SDALIGN for performance
- */
- if (write == 0 || pkt_len < 32)
+ /* Align Patch */
+ if (!write || pkt_len < 32)
pkt_len = (pkt_len + 3) & 0xFFFFFFFC;
else if (pkt_len % blk_size)
pkt_len += blk_size - (pkt_len % blk_size);
@@ -1137,87 +1143,51 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
*/
extern SDIOH_API_RC
sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func,
- uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt)
+ uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt)
{
SDIOH_API_RC Status;
- void *mypkt = NULL;
+ void *tmppkt;
+ void *orig_buf = NULL;
+ uint copylen = 0;
sd_trace(("%s: Enter\n", __FUNCTION__));
DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait);
DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
- /* Case 1: we don't have a packet. */
- if (pkt == NULL) {
- sd_data(("%s: Creating new %s Packet, len=%d\n",
- __FUNCTION__, write ? "TX" : "RX", buflen_u));
-#ifdef CONFIG_DHD_USE_STATIC_BUF
- if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) {
-#else
- if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) {
-#endif /* CONFIG_DHD_USE_STATIC_BUF */
- sd_err(("%s: PKTGET failed: len %d\n",
- __FUNCTION__, buflen_u));
- return SDIOH_API_RC_FAIL;
- }
- /* For a write, copy the buffer data into the packet. */
- if (write) {
- bcopy(buffer, PKTDATA(sd->osh, mypkt), buflen_u);
- }
-
- Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
-
- /* For a read, copy the packet data back to the buffer. */
- if (!write) {
- bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u);
- }
-#ifdef CONFIG_DHD_USE_STATIC_BUF
- PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE);
-#else
- PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE);
-#endif /* CONFIG_DHD_USE_STATIC_BUF */
- } else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) {
- /* Case 2: We have a packet, but it is unaligned. */
-
- /* In this case, we cannot have a chain. */
+ if (pkt == NULL) {
+ /* Case 1: we don't have a packet. */
+ orig_buf = buffer;
+ copylen = buflen_u;
+ } else if ((ulong)PKTDATA(sd->osh, pkt) & DMA_ALIGN_MASK) {
+ /* Case 2: We have a packet, but it is unaligned.
+ * in this case, we cannot have a chain.
+ */
ASSERT(PKTNEXT(sd->osh, pkt) == NULL);
- sd_data(("%s: Creating aligned %s Packet, len=%d\n",
- __FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt)));
-#ifdef CONFIG_DHD_USE_STATIC_BUF
- if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) {
-#else
- if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) {
-#endif /* CONFIG_DHD_USE_STATIC_BUF */
- sd_err(("%s: PKTGET failed: len %d\n",
- __FUNCTION__, PKTLEN(sd->osh, pkt)));
+ orig_buf = PKTDATA(sd->osh, pkt);
+ copylen = PKTLEN(sd->osh, pkt);
+ }
+
+ tmppkt = pkt;
+ if (copylen) {
+ tmppkt = PKTGET_STATIC(sd->osh, copylen, write ? TRUE : FALSE);
+ if (tmppkt == NULL) {
+ sd_err(("%s: PKTGET failed: len %d\n", __FUNCTION__, copylen));
return SDIOH_API_RC_FAIL;
}
-
/* For a write, copy the buffer data into the packet. */
- if (write) {
- bcopy(PKTDATA(sd->osh, pkt),
- PKTDATA(sd->osh, mypkt),
- PKTLEN(sd->osh, pkt));
- }
+ if (write)
+ bcopy(orig_buf, PKTDATA(sd->osh, tmppkt), copylen);
+ }
- Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
+ Status = sdioh_request_packet(sd, fix_inc, write, func, addr, tmppkt);
+ if (copylen) {
/* For a read, copy the packet data back to the buffer. */
- if (!write) {
- bcopy(PKTDATA(sd->osh, mypkt),
- PKTDATA(sd->osh, pkt),
- PKTLEN(sd->osh, mypkt));
- }
-#ifdef CONFIG_DHD_USE_STATIC_BUF
- PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE);
-#else
- PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE);
-#endif /* CONFIG_DHD_USE_STATIC_BUF */
- } else { /* case 3: We have a packet and it is aligned. */
- sd_data(("%s: Aligned %s Packet, direct DMA\n",
- __FUNCTION__, write ? "Tx" : "Rx"));
- Status = sdioh_request_packet(sd, fix_inc, write, func, addr, pkt);
+ if (!write)
+ bcopy(PKTDATA(sd->osh, tmppkt), orig_buf, PKTLEN(sd->osh, tmppkt));
+ PKTFREE_STATIC(sd->osh, tmppkt, write ? TRUE : FALSE);
}
return (Status);
@@ -1364,7 +1334,10 @@ sdioh_start(sdioh_info_t *si, int stage)
int ret;
sdioh_info_t *sd = gInstance->sd;
- if (!sd) return (0);
+ if (!sd) {
+ sd_err(("%s Failed, sd is NULL\n", __FUNCTION__));
+ return (0);
+ }
/* Need to do this stages as we can't enable the interrupt till
downloading of the firmware is complete, other wise polling