diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2013-03-15 12:54:01 -0700 |
---|---|---|
committer | Ziyan <jaraidaniel@gmail.com> | 2016-05-01 23:35:14 +0200 |
commit | fdc64453fdb3b6994b0e56fa542b8567bc24ba54 (patch) | |
tree | 7295d62f85aa21a88098edf037e16a577a2026e2 /drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c | |
parent | f2a2177f59124834879276a1aefcf47c68ec0416 (diff) | |
download | kernel_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.c | 173 |
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 |