summaryrefslogtreecommitdiff
path: root/drivers/staging/brcm80211/brcmfmac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/brcm80211/brcmfmac')
-rw-r--r--drivers/staging/brcm80211/brcmfmac/Makefile33
-rw-r--r--drivers/staging/brcm80211/brcmfmac/bcmchip.h32
-rw-r--r--drivers/staging/brcm80211/brcmfmac/bcmsdh.c371
-rw-r--r--drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c625
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd.h773
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_bus.h57
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_cdc.c498
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_common.c872
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_dbg.h58
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_linux.c1354
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_proto.h60
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_sdio.c4581
-rw-r--r--drivers/staging/brcm80211/brcmfmac/sdio_host.h252
-rw-r--r--drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c3730
-rw-r--r--drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h375
15 files changed, 0 insertions, 13671 deletions
diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile
deleted file mode 100644
index a1b7637dce31..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Makefile fragment for Broadcom 802.11n Networking Device Driver
-#
-# Copyright (c) 2010 Broadcom Corporation
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-ccflags-y += \
- -Idrivers/staging/brcm80211/brcmfmac \
- -Idrivers/staging/brcm80211/include
-
-DHDOFILES = \
- wl_cfg80211.o \
- dhd_cdc.o \
- dhd_common.o \
- dhd_sdio.o \
- dhd_linux.o \
- bcmsdh.o \
- bcmsdh_sdmmc.o
-
-obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
-brcmfmac-objs += $(DHDOFILES)
-ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmchip.h b/drivers/staging/brcm80211/brcmfmac/bcmchip.h
deleted file mode 100644
index d7d3afd5a10f..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/bcmchip.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2011 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _bcmchip_h_
-#define _bcmchip_h_
-
-/* bcm4329 */
-/* SDIO device core, ID 0x829 */
-#define BCM4329_CORE_BUS_BASE 0x18011000
-/* internal memory core, ID 0x80e */
-#define BCM4329_CORE_SOCRAM_BASE 0x18003000
-/* ARM Cortex M3 core, ID 0x82a */
-#define BCM4329_CORE_ARM_BASE 0x18002000
-#define BCM4329_RAMSIZE 0x48000
-/* firmware name */
-#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin"
-#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt"
-
-#endif /* _bcmchip_h_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
deleted file mode 100644
index bff9dcd6fadc..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-/* ****************** SDIO CARD Interface Functions **************************/
-
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/completion.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/card.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 "dhd_dbg.h"
-#include "sdio_host.h"
-
-#define SDIOH_API_ACCESS_RETRY_LIMIT 2
-
-static void brcmf_sdioh_irqhandler(struct sdio_func *func)
-{
- struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
-
- brcmf_dbg(TRACE, "***IRQHandler\n");
-
- sdio_release_host(func);
-
- brcmf_sdbrcm_isr(sdiodev->bus);
-
- sdio_claim_host(func);
-}
-
-int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev)
-{
- brcmf_dbg(TRACE, "Entering\n");
-
- sdio_claim_host(sdiodev->func[1]);
- sdio_claim_irq(sdiodev->func[1], brcmf_sdioh_irqhandler);
- sdio_release_host(sdiodev->func[1]);
-
- return 0;
-}
-
-int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev)
-{
- brcmf_dbg(TRACE, "Entering\n");
-
- sdio_claim_host(sdiodev->func[1]);
- sdio_release_irq(sdiodev->func[1]);
- sdio_release_host(sdiodev->func[1]);
-
- return 0;
-}
-
-u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
- int *err)
-{
- int status;
- s32 retry = 0;
- u8 data = 0;
-
- do {
- if (retry) /* wait for 1 ms till bus get settled down */
- udelay(1000);
- status = brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, fnc_num,
- addr, (u8 *) &data);
- } while (status != 0
- && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
- if (err)
- *err = status;
-
- brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
- fnc_num, addr, data);
-
- return data;
-}
-
-void
-brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
- u8 data, int *err)
-{
- int status;
- s32 retry = 0;
-
- do {
- if (retry) /* wait for 1 ms till bus get settled down */
- udelay(1000);
- status = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, fnc_num,
- addr, (u8 *) &data);
- } while (status != 0
- && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
- if (err)
- *err = status;
-
- brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
- fnc_num, addr, data);
-}
-
-int
-brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
-{
- int err = 0;
- brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
- (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
- if (!err)
- brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_SBADDRMID,
- (address >> 16) & SBSDIO_SBADDRMID_MASK,
- &err);
- if (!err)
- brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_SBADDRHIGH,
- (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
- &err);
-
- return err;
-}
-
-u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size)
-{
- int status;
- u32 word = 0;
- uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
-
- brcmf_dbg(INFO, "fun = 1, addr = 0x%x\n", addr);
-
- if (bar0 != sdiodev->sbwad) {
- if (brcmf_sdcard_set_sbaddr_window(sdiodev, bar0))
- return 0xFFFFFFFF;
-
- sdiodev->sbwad = bar0;
- }
-
- addr &= SBSDIO_SB_OFT_ADDR_MASK;
- if (size == 4)
- addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
-
- status = brcmf_sdioh_request_word(sdiodev, SDIOH_READ, SDIO_FUNC_1,
- addr, &word, size);
-
- sdiodev->regfail = (status != 0);
-
- brcmf_dbg(INFO, "u32data = 0x%x\n", word);
-
- /* if ok, return appropriately masked word */
- if (status == 0) {
- switch (size) {
- case sizeof(u8):
- return word & 0xff;
- case sizeof(u16):
- return word & 0xffff;
- case sizeof(u32):
- return word;
- default:
- sdiodev->regfail = true;
-
- }
- }
-
- /* otherwise, bad sdio access or invalid size */
- brcmf_dbg(ERROR, "error reading addr 0x%04x size %d\n", addr, size);
- return 0xFFFFFFFF;
-}
-
-u32 brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
- u32 data)
-{
- int status;
- uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
- int err = 0;
-
- brcmf_dbg(INFO, "fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
- addr, size * 8, data);
-
- if (bar0 != sdiodev->sbwad) {
- err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
- if (err)
- return err;
-
- sdiodev->sbwad = bar0;
- }
-
- addr &= SBSDIO_SB_OFT_ADDR_MASK;
- if (size == 4)
- addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
- status =
- brcmf_sdioh_request_word(sdiodev, SDIOH_WRITE, SDIO_FUNC_1,
- addr, &data, size);
- sdiodev->regfail = (status != 0);
-
- if (status == 0)
- return 0;
-
- brcmf_dbg(ERROR, "error writing 0x%08x to addr 0x%04x size %d\n",
- data, addr, size);
- return 0xFFFFFFFF;
-}
-
-bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev)
-{
- return sdiodev->regfail;
-}
-
-int
-brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
- uint flags,
- u8 *buf, uint nbytes, struct sk_buff *pkt)
-{
- int status;
- uint incr_fix;
- uint width;
- uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
- int err = 0;
-
- brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
-
- /* Async not implemented yet */
- if (flags & SDIO_REQ_ASYNC)
- return -ENOTSUPP;
-
- if (bar0 != sdiodev->sbwad) {
- err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
- if (err)
- return err;
-
- sdiodev->sbwad = bar0;
- }
-
- addr &= SBSDIO_SB_OFT_ADDR_MASK;
-
- incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
- width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- if (width == 4)
- addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
-
- status = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
- fn, addr, width, nbytes, buf, pkt);
-
- return status;
-}
-
-int
-brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
- uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt)
-{
- uint incr_fix;
- uint width;
- uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
- int err = 0;
-
- brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
-
- /* Async not implemented yet */
- if (flags & SDIO_REQ_ASYNC)
- return -ENOTSUPP;
-
- if (bar0 != sdiodev->sbwad) {
- err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
- if (err)
- return err;
-
- sdiodev->sbwad = bar0;
- }
-
- addr &= SBSDIO_SB_OFT_ADDR_MASK;
-
- incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
- width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- if (width == 4)
- addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
-
- return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
- addr, width, nbytes, buf, pkt);
-}
-
-int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
- u8 *buf, uint nbytes)
-{
- addr &= SBSDIO_SB_OFT_ADDR_MASK;
- addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
-
- return brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC,
- (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
- addr, 4, nbytes, buf, NULL);
-}
-
-int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
-{
- char t_func = (char)fn;
- brcmf_dbg(TRACE, "Enter\n");
-
- /* issue abort cmd52 command through F0 */
- brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
- SDIO_CCCR_ABORT, &t_func);
-
- brcmf_dbg(TRACE, "Exit\n");
- return 0;
-}
-
-int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
-{
- u32 regs = 0;
- int ret = 0;
-
- ret = brcmf_sdioh_attach(sdiodev);
- if (ret)
- goto out;
-
- regs = SI_ENUM_BASE;
-
- /* Report the BAR, to fix if needed */
- sdiodev->sbwad = SI_ENUM_BASE;
-
- /* try to attach to the target device */
- sdiodev->bus = brcmf_sdbrcm_probe(0, 0, 0, 0, regs, sdiodev);
- if (!sdiodev->bus) {
- brcmf_dbg(ERROR, "device attach failed\n");
- ret = -ENODEV;
- goto out;
- }
-
-out:
- if (ret)
- brcmf_sdio_remove(sdiodev);
-
- return ret;
-}
-EXPORT_SYMBOL(brcmf_sdio_probe);
-
-int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
-{
- if (sdiodev->bus) {
- brcmf_sdbrcm_disconnect(sdiodev->bus);
- sdiodev->bus = NULL;
- }
-
- brcmf_sdioh_detach(sdiodev);
-
- sdiodev->sbwad = 0;
-
- return 0;
-}
-EXPORT_SYMBOL(brcmf_sdio_remove);
-
-void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
-{
- if (enable)
- brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
- else
- brcmf_sdbrcm_wd_timer(sdiodev->bus, 0);
-}
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
deleted file mode 100644
index e919de210f70..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/core.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/card.h>
-#include <linux/suspend.h>
-#include <linux/errno.h>
-#include <linux/sched.h> /* request_irq() */
-#include <net/cfg80211.h>
-
-#include <defs.h>
-#include <brcm_hw_ids.h>
-#include <brcmu_utils.h>
-#include <brcmu_wifi.h>
-#include "sdio_host.h"
-#include "dhd.h"
-#include "dhd_dbg.h"
-#include "wl_cfg80211.h"
-
-#define SDIO_VENDOR_ID_BROADCOM 0x02d0
-
-#define DMA_ALIGN_MASK 0x03
-
-#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
-
-#define SDIO_FUNC1_BLOCKSIZE 64
-#define SDIO_FUNC2_BLOCKSIZE 512
-
-/* devices we support, null terminated */
-static const struct sdio_device_id brcmf_sdmmc_ids[] = {
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
- { /* end: all zeroes */ },
-};
-MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
-
-static bool
-brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
-{
- bool is_err = false;
-#ifdef CONFIG_PM_SLEEP
- is_err = atomic_read(&sdiodev->suspend);
-#endif
- return is_err;
-}
-
-static void
-brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
-{
-#ifdef CONFIG_PM_SLEEP
- int retry = 0;
- while (atomic_read(&sdiodev->suspend) && retry++ != 30)
- wait_event_timeout(*wq, false, HZ/100);
-#endif
-}
-
-static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
- uint regaddr, u8 *byte)
-{
- struct sdio_func *sdfunc = sdiodev->func[0];
- int err_ret;
-
- /*
- * Can only directly write to some F0 registers.
- * Handle F2 enable/disable and Abort command
- * as a special case.
- */
- if (regaddr == SDIO_CCCR_IOEx) {
- sdfunc = sdiodev->func[2];
- if (sdfunc) {
- sdio_claim_host(sdfunc);
- if (*byte & SDIO_FUNC_ENABLE_2) {
- /* Enable Function 2 */
- err_ret = sdio_enable_func(sdfunc);
- if (err_ret)
- brcmf_dbg(ERROR,
- "enable F2 failed:%d\n",
- err_ret);
- } else {
- /* Disable Function 2 */
- err_ret = sdio_disable_func(sdfunc);
- if (err_ret)
- brcmf_dbg(ERROR,
- "Disable F2 failed:%d\n",
- err_ret);
- }
- sdio_release_host(sdfunc);
- }
- } else if (regaddr == SDIO_CCCR_ABORT) {
- sdio_claim_host(sdfunc);
- sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
- sdio_release_host(sdfunc);
- } else if (regaddr < 0xF0) {
- brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
- err_ret = -EPERM;
- } else {
- sdio_claim_host(sdfunc);
- sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
- sdio_release_host(sdfunc);
- }
-
- return err_ret;
-}
-
-int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
- uint regaddr, u8 *byte)
-{
- int err_ret;
-
- brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
-
- brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
- if (brcmf_pm_resume_error(sdiodev))
- return -EIO;
-
- if (rw && func == 0) {
- /* handle F0 separately */
- err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
- } else {
- sdio_claim_host(sdiodev->func[func]);
- if (rw) /* CMD52 Write */
- sdio_writeb(sdiodev->func[func], *byte, regaddr,
- &err_ret);
- else if (func == 0) {
- *byte = sdio_f0_readb(sdiodev->func[func], regaddr,
- &err_ret);
- } else {
- *byte = sdio_readb(sdiodev->func[func], regaddr,
- &err_ret);
- }
- sdio_release_host(sdiodev->func[func]);
- }
-
- if (err_ret)
- brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
- rw ? "write" : "read", func, regaddr, *byte, err_ret);
-
- return err_ret;
-}
-
-int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
- uint rw, uint func, uint addr, u32 *word,
- uint nbytes)
-{
- int err_ret = -EIO;
-
- if (func == 0) {
- brcmf_dbg(ERROR, "Only CMD52 allowed to F0\n");
- return -EINVAL;
- }
-
- brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
- rw, func, addr, nbytes);
-
- brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
- if (brcmf_pm_resume_error(sdiodev))
- return -EIO;
- /* Claim host controller */
- sdio_claim_host(sdiodev->func[func]);
-
- if (rw) { /* CMD52 Write */
- if (nbytes == 4)
- sdio_writel(sdiodev->func[func], *word, addr,
- &err_ret);
- else if (nbytes == 2)
- sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
- addr, &err_ret);
- else
- brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
- } else { /* CMD52 Read */
- if (nbytes == 4)
- *word = sdio_readl(sdiodev->func[func], addr, &err_ret);
- else if (nbytes == 2)
- *word = sdio_readw(sdiodev->func[func], addr,
- &err_ret) & 0xFFFF;
- else
- brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
- }
-
- /* Release host controller */
- sdio_release_host(sdiodev->func[func]);
-
- if (err_ret)
- brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n",
- rw ? "write" : "read", err_ret);
-
- return err_ret;
-}
-
-static int
-brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
- uint write, uint func, uint addr,
- struct sk_buff *pkt)
-{
- bool fifo = (fix_inc == SDIOH_DATA_FIX);
- u32 SGCount = 0;
- int err_ret = 0;
-
- struct sk_buff *pnext;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- brcmf_pm_resume_wait(sdiodev, &sdiodev->request_packet_wait);
- if (brcmf_pm_resume_error(sdiodev))
- return -EIO;
-
- /* Claim host controller */
- sdio_claim_host(sdiodev->func[func]);
- for (pnext = pkt; pnext; pnext = pnext->next) {
- uint pkt_len = pnext->len;
- pkt_len += 3;
- pkt_len &= 0xFFFFFFFC;
-
- if ((write) && (!fifo)) {
- err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
- ((u8 *) (pnext->data)),
- pkt_len);
- } else if (write) {
- err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
- ((u8 *) (pnext->data)),
- pkt_len);
- } else if (fifo) {
- err_ret = sdio_readsb(sdiodev->func[func],
- ((u8 *) (pnext->data)),
- addr, pkt_len);
- } else {
- err_ret = sdio_memcpy_fromio(sdiodev->func[func],
- ((u8 *) (pnext->data)),
- addr, pkt_len);
- }
-
- if (err_ret) {
- brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
- write ? "TX" : "RX", pnext, SGCount, addr,
- pkt_len, err_ret);
- } else {
- brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
- write ? "TX" : "RX", pnext, SGCount, addr,
- pkt_len);
- }
-
- if (!fifo)
- addr += pkt_len;
- SGCount++;
-
- }
-
- /* Release host controller */
- sdio_release_host(sdiodev->func[func]);
-
- brcmf_dbg(TRACE, "Exit\n");
- return err_ret;
-}
-
-/*
- * This function takes a buffer or packet, and fixes everything up
- * so that in the end, a DMA-able packet is created.
- *
- * A buffer does not have an associated packet pointer,
- * and may or may not be aligned.
- * A packet may consist of a single packet, or a packet chain.
- * If it is a packet chain, then all the packets in the chain
- * must be properly aligned.
- *
- * If the packet data is not aligned, then there may only be
- * one packet, and in this case, it is copied to a new
- * aligned packet.
- *
- */
-int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
- uint fix_inc, uint write, uint func, uint addr,
- uint reg_width, uint buflen_u, u8 *buffer,
- struct sk_buff *pkt)
-{
- int Status;
- struct sk_buff *mypkt = NULL;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
- if (brcmf_pm_resume_error(sdiodev))
- return -EIO;
- /* Case 1: we don't have a packet. */
- if (pkt == NULL) {
- brcmf_dbg(DATA, "Creating new %s Packet, len=%d\n",
- write ? "TX" : "RX", buflen_u);
- mypkt = brcmu_pkt_buf_get_skb(buflen_u);
- if (!mypkt) {
- brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
- buflen_u);
- return -EIO;
- }
-
- /* For a write, copy the buffer data into the packet. */
- if (write)
- memcpy(mypkt->data, buffer, buflen_u);
-
- Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
- func, addr, mypkt);
-
- /* For a read, copy the packet data back to the buffer. */
- if (!write)
- memcpy(buffer, mypkt->data, buflen_u);
-
- brcmu_pkt_buf_free_skb(mypkt);
- } else if (((ulong) (pkt->data) & DMA_ALIGN_MASK) != 0) {
- /*
- * Case 2: We have a packet, but it is unaligned.
- * In this case, we cannot have a chain (pkt->next == NULL)
- */
- brcmf_dbg(DATA, "Creating aligned %s Packet, len=%d\n",
- write ? "TX" : "RX", pkt->len);
- mypkt = brcmu_pkt_buf_get_skb(pkt->len);
- if (!mypkt) {
- brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
- pkt->len);
- return -EIO;
- }
-
- /* For a write, copy the buffer data into the packet. */
- if (write)
- memcpy(mypkt->data, pkt->data, pkt->len);
-
- Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
- func, addr, mypkt);
-
- /* For a read, copy the packet data back to the buffer. */
- if (!write)
- memcpy(pkt->data, mypkt->data, mypkt->len);
-
- brcmu_pkt_buf_free_skb(mypkt);
- } else { /* case 3: We have a packet and
- it is aligned. */
- brcmf_dbg(DATA, "Aligned %s Packet, direct DMA\n",
- write ? "Tx" : "Rx");
- Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
- func, addr, pkt);
- }
-
- return Status;
-}
-
-/* Read client card reg */
-static int
-brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr,
- int regsize, u32 *data)
-{
-
- if ((func == 0) || (regsize == 1)) {
- u8 temp = 0;
-
- brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, func, regaddr,
- &temp);
- *data = temp;
- *data &= 0xff;
- brcmf_dbg(DATA, "byte read data=0x%02x\n", *data);
- } else {
- brcmf_sdioh_request_word(sdiodev, SDIOH_READ, func, regaddr,
- data, regsize);
- if (regsize == 2)
- *data &= 0xffff;
-
- brcmf_dbg(DATA, "word read data=0x%08x\n", *data);
- }
-
- return SUCCESS;
-}
-
-static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
-{
- /* read 24 bits and return valid 17 bit addr */
- int i;
- u32 scratch, regdata;
- __le32 scratch_le;
- u8 *ptr = (u8 *)&scratch_le;
-
- for (i = 0; i < 3; i++) {
- if ((brcmf_sdioh_card_regread(sdiodev, 0, regaddr, 1,
- &regdata)) != SUCCESS)
- brcmf_dbg(ERROR, "Can't read!\n");
-
- *ptr++ = (u8) regdata;
- regaddr++;
- }
-
- /* Only the lower 17-bits are valid */
- scratch = le32_to_cpu(scratch_le);
- scratch &= 0x0001FFFF;
- return scratch;
-}
-
-static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
-{
- int err_ret;
- u32 fbraddr;
- u8 func;
-
- brcmf_dbg(TRACE, "\n");
-
- /* Get the Card's common CIS address */
- sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
- SDIO_CCCR_CIS);
- brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n",
- sdiodev->func_cis_ptr[0]);
-
- /* Get the Card's function CIS (for each function) */
- for (fbraddr = SDIO_FBR_BASE(1), func = 1;
- func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
- sdiodev->func_cis_ptr[func] =
- brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
- brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n",
- func, sdiodev->func_cis_ptr[func]);
- }
-
- /* Enable Function 1 */
- sdio_claim_host(sdiodev->func[1]);
- err_ret = sdio_enable_func(sdiodev->func[1]);
- sdio_release_host(sdiodev->func[1]);
- if (err_ret)
- brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
-
- return false;
-}
-
-/*
- * Public entry points & extern's
- */
-int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
-{
- int err_ret = 0;
-
- brcmf_dbg(TRACE, "\n");
-
- sdiodev->num_funcs = 2;
-
- sdio_claim_host(sdiodev->func[1]);
- err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
- sdio_release_host(sdiodev->func[1]);
- if (err_ret) {
- brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
- goto out;
- }
-
- sdio_claim_host(sdiodev->func[2]);
- err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
- sdio_release_host(sdiodev->func[2]);
- if (err_ret) {
- brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
- goto out;
- }
-
- brcmf_sdioh_enablefuncs(sdiodev);
-
-out:
- brcmf_dbg(TRACE, "Done\n");
- return err_ret;
-}
-
-void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
-{
- brcmf_dbg(TRACE, "\n");
-
- /* Disable Function 2 */
- sdio_claim_host(sdiodev->func[2]);
- sdio_disable_func(sdiodev->func[2]);
- sdio_release_host(sdiodev->func[2]);
-
- /* Disable Function 1 */
- sdio_claim_host(sdiodev->func[1]);
- sdio_disable_func(sdiodev->func[1]);
- sdio_release_host(sdiodev->func[1]);
-
-}
-
-static int brcmf_ops_sdio_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
-{
- int ret = 0;
- struct brcmf_sdio_dev *sdiodev;
- brcmf_dbg(TRACE, "Enter\n");
- brcmf_dbg(TRACE, "func->class=%x\n", func->class);
- brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
- brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
- brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);
-
- if (func->num == 1) {
- if (dev_get_drvdata(&func->card->dev)) {
- brcmf_dbg(ERROR, "card private drvdata occupied\n");
- return -ENXIO;
- }
- sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
- if (!sdiodev)
- return -ENOMEM;
- sdiodev->func[0] = func->card->sdio_func[0];
- sdiodev->func[1] = func;
- dev_set_drvdata(&func->card->dev, sdiodev);
-
- atomic_set(&sdiodev->suspend, false);
- init_waitqueue_head(&sdiodev->request_byte_wait);
- init_waitqueue_head(&sdiodev->request_word_wait);
- init_waitqueue_head(&sdiodev->request_packet_wait);
- init_waitqueue_head(&sdiodev->request_buffer_wait);
- }
-
- if (func->num == 2) {
- sdiodev = dev_get_drvdata(&func->card->dev);
- if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
- return -ENODEV;
- sdiodev->func[2] = func;
-
- brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
- ret = brcmf_sdio_probe(sdiodev);
- }
-
- return ret;
-}
-
-static void brcmf_ops_sdio_remove(struct sdio_func *func)
-{
- struct brcmf_sdio_dev *sdiodev;
- brcmf_dbg(TRACE, "Enter\n");
- brcmf_dbg(INFO, "func->class=%x\n", func->class);
- brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
- brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
- brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
-
- if (func->num == 2) {
- sdiodev = dev_get_drvdata(&func->card->dev);
- brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
- brcmf_sdio_remove(sdiodev);
- dev_set_drvdata(&func->card->dev, NULL);
- kfree(sdiodev);
- }
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int brcmf_sdio_suspend(struct device *dev)
-{
- mmc_pm_flag_t sdio_flags;
- struct brcmf_sdio_dev *sdiodev;
- struct sdio_func *func = dev_to_sdio_func(dev);
- int ret = 0;
-
- brcmf_dbg(TRACE, "\n");
-
- sdiodev = dev_get_drvdata(&func->card->dev);
-
- atomic_set(&sdiodev->suspend, true);
-
- sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
- if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
- brcmf_dbg(ERROR, "Host can't keep power while suspended\n");
- return -EINVAL;
- }
-
- ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
- if (ret) {
- brcmf_dbg(ERROR, "Failed to set pm_flags\n");
- return ret;
- }
-
- brcmf_sdio_wdtmr_enable(sdiodev, false);
-
- return ret;
-}
-
-static int brcmf_sdio_resume(struct device *dev)
-{
- struct brcmf_sdio_dev *sdiodev;
- struct sdio_func *func = dev_to_sdio_func(dev);
-
- sdiodev = dev_get_drvdata(&func->card->dev);
- brcmf_sdio_wdtmr_enable(sdiodev, true);
- atomic_set(&sdiodev->suspend, false);
- return 0;
-}
-
-static const struct dev_pm_ops brcmf_sdio_pm_ops = {
- .suspend = brcmf_sdio_suspend,
- .resume = brcmf_sdio_resume,
-};
-#endif /* CONFIG_PM_SLEEP */
-
-static struct sdio_driver brcmf_sdmmc_driver = {
- .probe = brcmf_ops_sdio_probe,
- .remove = brcmf_ops_sdio_remove,
- .name = "brcmfmac",
- .id_table = brcmf_sdmmc_ids,
-#ifdef CONFIG_PM_SLEEP
- .drv = {
- .pm = &brcmf_sdio_pm_ops,
- },
-#endif /* CONFIG_PM_SLEEP */
-};
-
-/* bus register interface */
-int brcmf_bus_register(void)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- return sdio_register_driver(&brcmf_sdmmc_driver);
-}
-
-void brcmf_bus_unregister(void)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- sdio_unregister_driver(&brcmf_sdmmc_driver);
-}
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h
deleted file mode 100644
index 3ec74778b2e3..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/dhd.h
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/****************
- * Common types *
- */
-
-#ifndef _BRCMF_H_
-#define _BRCMF_H_
-
-#define BRCMF_VERSION_STR "4.218.248.5"
-
-/*******************************************************************************
- * IO codes that are interpreted by dongle firmware
- ******************************************************************************/
-#define BRCMF_C_UP 2
-#define BRCMF_C_SET_PROMISC 10
-#define BRCMF_C_GET_RATE 12
-#define BRCMF_C_GET_INFRA 19
-#define BRCMF_C_SET_INFRA 20
-#define BRCMF_C_GET_AUTH 21
-#define BRCMF_C_SET_AUTH 22
-#define BRCMF_C_GET_BSSID 23
-#define BRCMF_C_GET_SSID 25
-#define BRCMF_C_SET_SSID 26
-#define BRCMF_C_GET_CHANNEL 29
-#define BRCMF_C_GET_SRL 31
-#define BRCMF_C_GET_LRL 33
-#define BRCMF_C_GET_RADIO 37
-#define BRCMF_C_SET_RADIO 38
-#define BRCMF_C_GET_PHYTYPE 39
-#define BRCMF_C_SET_KEY 45
-#define BRCMF_C_SET_PASSIVE_SCAN 49
-#define BRCMF_C_SCAN 50
-#define BRCMF_C_SCAN_RESULTS 51
-#define BRCMF_C_DISASSOC 52
-#define BRCMF_C_REASSOC 53
-#define BRCMF_C_SET_ROAM_TRIGGER 55
-#define BRCMF_C_SET_ROAM_DELTA 57
-#define BRCMF_C_GET_DTIMPRD 77
-#define BRCMF_C_SET_COUNTRY 84
-#define BRCMF_C_GET_PM 85
-#define BRCMF_C_SET_PM 86
-#define BRCMF_C_GET_AP 117
-#define BRCMF_C_SET_AP 118
-#define BRCMF_C_GET_RSSI 127
-#define BRCMF_C_GET_WSEC 133
-#define BRCMF_C_SET_WSEC 134
-#define BRCMF_C_GET_PHY_NOISE 135
-#define BRCMF_C_GET_BSS_INFO 136
-#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
-#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
-#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
-#define BRCMF_C_GET_VALID_CHANNELS 217
-#define BRCMF_C_GET_KEY_PRIMARY 235
-#define BRCMF_C_SET_KEY_PRIMARY 236
-#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
-#define BRCMF_C_GET_VAR 262
-#define BRCMF_C_SET_VAR 263
-
-/* phy types (returned by WLC_GET_PHYTPE) */
-#define WLC_PHY_TYPE_A 0
-#define WLC_PHY_TYPE_B 1
-#define WLC_PHY_TYPE_G 2
-#define WLC_PHY_TYPE_N 4
-#define WLC_PHY_TYPE_LP 5
-#define WLC_PHY_TYPE_SSN 6
-#define WLC_PHY_TYPE_HT 7
-#define WLC_PHY_TYPE_LCN 8
-#define WLC_PHY_TYPE_NULL 0xf
-
-#define BRCMF_EVENTING_MASK_LEN 16
-
-#define TOE_TX_CSUM_OL 0x00000001
-#define TOE_RX_CSUM_OL 0x00000002
-
-#define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */
-
-/* size of brcmf_scan_params not including variable length array */
-#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
-
-/* masks for channel and ssid count */
-#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
-#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
-
-#define BRCMF_SCAN_ACTION_START 1
-#define BRCMF_SCAN_ACTION_CONTINUE 2
-#define WL_SCAN_ACTION_ABORT 3
-
-#define BRCMF_ISCAN_REQ_VERSION 1
-
-/* brcmf_iscan_results status values */
-#define BRCMF_SCAN_RESULTS_SUCCESS 0
-#define BRCMF_SCAN_RESULTS_PARTIAL 1
-#define BRCMF_SCAN_RESULTS_PENDING 2
-#define BRCMF_SCAN_RESULTS_ABORTED 3
-#define BRCMF_SCAN_RESULTS_NO_MEM 4
-
-/* Indicates this key is using soft encrypt */
-#define WL_SOFT_KEY (1 << 0)
-/* primary (ie tx) key */
-#define BRCMF_PRIMARY_KEY (1 << 1)
-/* Reserved for backward compat */
-#define WL_KF_RES_4 (1 << 4)
-/* Reserved for backward compat */
-#define WL_KF_RES_5 (1 << 5)
-/* Indicates a group key for a IBSS PEER */
-#define WL_IBSS_PEER_GROUP_KEY (1 << 6)
-
-/* For supporting multiple interfaces */
-#define BRCMF_MAX_IFS 16
-#define BRCMF_DEL_IF -0xe
-#define BRCMF_BAD_IF -0xf
-
-#define DOT11_BSSTYPE_ANY 2
-#define DOT11_MAX_DEFAULT_KEYS 4
-
-#define BRCMF_EVENT_MSG_LINK 0x01
-#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
-#define BRCMF_EVENT_MSG_GROUP 0x04
-
-struct brcmf_event_msg {
- __be16 version;
- __be16 flags;
- __be32 event_type;
- __be32 status;
- __be32 reason;
- __be32 auth_type;
- __be32 datalen;
- u8 addr[ETH_ALEN];
- char ifname[IFNAMSIZ];
-} __packed;
-
-struct brcm_ethhdr {
- u16 subtype;
- u16 length;
- u8 version;
- u8 oui[3];
- u16 usr_subtype;
-} __packed;
-
-struct brcmf_event {
- struct ethhdr eth;
- struct brcm_ethhdr hdr;
- struct brcmf_event_msg msg;
-} __packed;
-
-struct dngl_stats {
- unsigned long rx_packets; /* total packets received */
- unsigned long tx_packets; /* total packets transmitted */
- unsigned long rx_bytes; /* total bytes received */
- unsigned long tx_bytes; /* total bytes transmitted */
- unsigned long rx_errors; /* bad packets received */
- unsigned long tx_errors; /* packet transmit problems */
- unsigned long rx_dropped; /* packets dropped by dongle */
- unsigned long tx_dropped; /* packets dropped by dongle */
- unsigned long multicast; /* multicast packets received */
-};
-
-/* event codes sent by the dongle to this driver */
-#define BRCMF_E_SET_SSID 0
-#define BRCMF_E_JOIN 1
-#define BRCMF_E_START 2
-#define BRCMF_E_AUTH 3
-#define BRCMF_E_AUTH_IND 4
-#define BRCMF_E_DEAUTH 5
-#define BRCMF_E_DEAUTH_IND 6
-#define BRCMF_E_ASSOC 7
-#define BRCMF_E_ASSOC_IND 8
-#define BRCMF_E_REASSOC 9
-#define BRCMF_E_REASSOC_IND 10
-#define BRCMF_E_DISASSOC 11
-#define BRCMF_E_DISASSOC_IND 12
-#define BRCMF_E_QUIET_START 13
-#define BRCMF_E_QUIET_END 14
-#define BRCMF_E_BEACON_RX 15
-#define BRCMF_E_LINK 16
-#define BRCMF_E_MIC_ERROR 17
-#define BRCMF_E_NDIS_LINK 18
-#define BRCMF_E_ROAM 19
-#define BRCMF_E_TXFAIL 20
-#define BRCMF_E_PMKID_CACHE 21
-#define BRCMF_E_RETROGRADE_TSF 22
-#define BRCMF_E_PRUNE 23
-#define BRCMF_E_AUTOAUTH 24
-#define BRCMF_E_EAPOL_MSG 25
-#define BRCMF_E_SCAN_COMPLETE 26
-#define BRCMF_E_ADDTS_IND 27
-#define BRCMF_E_DELTS_IND 28
-#define BRCMF_E_BCNSENT_IND 29
-#define BRCMF_E_BCNRX_MSG 30
-#define BRCMF_E_BCNLOST_MSG 31
-#define BRCMF_E_ROAM_PREP 32
-#define BRCMF_E_PFN_NET_FOUND 33
-#define BRCMF_E_PFN_NET_LOST 34
-#define BRCMF_E_RESET_COMPLETE 35
-#define BRCMF_E_JOIN_START 36
-#define BRCMF_E_ROAM_START 37
-#define BRCMF_E_ASSOC_START 38
-#define BRCMF_E_IBSS_ASSOC 39
-#define BRCMF_E_RADIO 40
-#define BRCMF_E_PSM_WATCHDOG 41
-#define BRCMF_E_PROBREQ_MSG 44
-#define BRCMF_E_SCAN_CONFIRM_IND 45
-#define BRCMF_E_PSK_SUP 46
-#define BRCMF_E_COUNTRY_CODE_CHANGED 47
-#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48
-#define BRCMF_E_ICV_ERROR 49
-#define BRCMF_E_UNICAST_DECODE_ERROR 50
-#define BRCMF_E_MULTICAST_DECODE_ERROR 51
-#define BRCMF_E_TRACE 52
-#define BRCMF_E_IF 54
-#define BRCMF_E_RSSI 56
-#define BRCMF_E_PFN_SCAN_COMPLETE 57
-#define BRCMF_E_EXTLOG_MSG 58
-#define BRCMF_E_ACTION_FRAME 59
-#define BRCMF_E_ACTION_FRAME_COMPLETE 60
-#define BRCMF_E_PRE_ASSOC_IND 61
-#define BRCMF_E_PRE_REASSOC_IND 62
-#define BRCMF_E_CHANNEL_ADOPTED 63
-#define BRCMF_E_AP_STARTED 64
-#define BRCMF_E_DFS_AP_STOP 65
-#define BRCMF_E_DFS_AP_RESUME 66
-#define BRCMF_E_RESERVED1 67
-#define BRCMF_E_RESERVED2 68
-#define BRCMF_E_ESCAN_RESULT 69
-#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70
-#define BRCMF_E_DCS_REQUEST 73
-
-#define BRCMF_E_FIFO_CREDIT_MAP 74
-
-#define BRCMF_E_LAST 75
-
-#define BRCMF_E_STATUS_SUCCESS 0
-#define BRCMF_E_STATUS_FAIL 1
-#define BRCMF_E_STATUS_TIMEOUT 2
-#define BRCMF_E_STATUS_NO_NETWORKS 3
-#define BRCMF_E_STATUS_ABORT 4
-#define BRCMF_E_STATUS_NO_ACK 5
-#define BRCMF_E_STATUS_UNSOLICITED 6
-#define BRCMF_E_STATUS_ATTEMPT 7
-#define BRCMF_E_STATUS_PARTIAL 8
-#define BRCMF_E_STATUS_NEWSCAN 9
-#define BRCMF_E_STATUS_NEWASSOC 10
-#define BRCMF_E_STATUS_11HQUIET 11
-#define BRCMF_E_STATUS_SUPPRESS 12
-#define BRCMF_E_STATUS_NOCHANS 13
-#define BRCMF_E_STATUS_CS_ABORT 15
-#define BRCMF_E_STATUS_ERROR 16
-
-#define BRCMF_E_REASON_INITIAL_ASSOC 0
-#define BRCMF_E_REASON_LOW_RSSI 1
-#define BRCMF_E_REASON_DEAUTH 2
-#define BRCMF_E_REASON_DISASSOC 3
-#define BRCMF_E_REASON_BCNS_LOST 4
-#define BRCMF_E_REASON_MINTXRATE 9
-#define BRCMF_E_REASON_TXFAIL 10
-
-#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
-#define BRCMF_E_REASON_DIRECTED_ROAM 6
-#define BRCMF_E_REASON_TSPEC_REJECTED 7
-#define BRCMF_E_REASON_BETTER_AP 8
-
-#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
-#define BRCMF_E_PRUNE_BCAST_BSSID 2
-#define BRCMF_E_PRUNE_MAC_DENY 3
-#define BRCMF_E_PRUNE_MAC_NA 4
-#define BRCMF_E_PRUNE_REG_PASSV 5
-#define BRCMF_E_PRUNE_SPCT_MGMT 6
-#define BRCMF_E_PRUNE_RADAR 7
-#define BRCMF_E_RSN_MISMATCH 8
-#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
-#define BRCMF_E_PRUNE_BASIC_RATES 10
-#define BRCMF_E_PRUNE_CIPHER_NA 12
-#define BRCMF_E_PRUNE_KNOWN_STA 13
-#define BRCMF_E_PRUNE_WDS_PEER 15
-#define BRCMF_E_PRUNE_QBSS_LOAD 16
-#define BRCMF_E_PRUNE_HOME_AP 17
-
-#define BRCMF_E_SUP_OTHER 0
-#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
-#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
-#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
-#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
-#define BRCMF_E_SUP_PW_KEY_CIPHER 5
-#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
-#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
-#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
-#define BRCMF_E_SUP_MSG3_NO_GTK 9
-#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
-#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
-#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
-#define BRCMF_E_SUP_SEND_FAIL 13
-#define BRCMF_E_SUP_DEAUTH 14
-
-#define BRCMF_E_IF_ADD 1
-#define BRCMF_E_IF_DEL 2
-#define BRCMF_E_IF_CHANGE 3
-
-#define BRCMF_E_IF_ROLE_STA 0
-#define BRCMF_E_IF_ROLE_AP 1
-#define BRCMF_E_IF_ROLE_WDS 2
-
-#define BRCMF_E_LINK_BCN_LOSS 1
-#define BRCMF_E_LINK_DISASSOC 2
-#define BRCMF_E_LINK_ASSOC_REC 3
-#define BRCMF_E_LINK_BSSCFG_DIS 4
-
-/* The level of bus communication with the dongle */
-enum brcmf_bus_state {
- BRCMF_BUS_DOWN, /* Not ready for frame transfers */
- BRCMF_BUS_LOAD, /* Download access only (CPU reset) */
- BRCMF_BUS_DATA /* Ready for frame transfers */
-};
-
-/* Pattern matching filter. Specifies an offset within received packets to
- * start matching, the pattern to match, the size of the pattern, and a bitmask
- * that indicates which bits within the pattern should be matched.
- */
-struct brcmf_pkt_filter_pattern {
- /*
- * Offset within received packet to start pattern matching.
- * Offset '0' is the first byte of the ethernet header.
- */
- u32 offset;
- /* Size of the pattern. Bitmask must be the same size.*/
- u32 size_bytes;
- /*
- * Variable length mask and pattern data. mask starts at offset 0.
- * Pattern immediately follows mask.
- */
- u8 mask_and_pattern[1];
-};
-
-/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
-struct brcmf_pkt_filter {
- u32 id; /* Unique filter id, specified by app. */
- u32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
- u32 negate_match; /* Negate the result of filter matches */
- union { /* Filter definitions */
- struct brcmf_pkt_filter_pattern pattern; /* Filter pattern */
- } u;
-};
-
-/* IOVAR "pkt_filter_enable" parameter. */
-struct brcmf_pkt_filter_enable {
- u32 id; /* Unique filter id */
- u32 enable; /* Enable/disable bool */
-};
-
-/* BSS info structure
- * Applications MUST CHECK ie_offset field and length field to access IEs and
- * next bss_info structure in a vector (in struct brcmf_scan_results)
- */
-struct brcmf_bss_info {
- __le32 version; /* version field */
- __le32 length; /* byte length of data in this record,
- * starting at version and including IEs
- */
- u8 BSSID[ETH_ALEN];
- __le16 beacon_period; /* units are Kusec */
- __le16 capability; /* Capability information */
- u8 SSID_len;
- u8 SSID[32];
- struct {
- __le32 count; /* # rates in this set */
- u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
- } rateset; /* supported rates */
- __le16 chanspec; /* chanspec for bss */
- __le16 atim_window; /* units are Kusec */
- u8 dtim_period; /* DTIM period */
- __le16 RSSI; /* receive signal strength (in dBm) */
- s8 phy_noise; /* noise (in dBm) */
-
- u8 n_cap; /* BSS is 802.11N Capable */
- /* 802.11N BSS Capabilities (based on HT_CAP_*): */
- __le32 nbss_cap;
- u8 ctl_ch; /* 802.11N BSS control channel number */
- __le32 reserved32[1]; /* Reserved for expansion of BSS properties */
- u8 flags; /* flags */
- u8 reserved[3]; /* Reserved for expansion of BSS properties */
- u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
-
- __le16 ie_offset; /* offset at which IEs start, from beginning */
- __le32 ie_length; /* byte length of Information Elements */
- __le16 SNR; /* average SNR of during frame reception */
- /* Add new fields here */
- /* variable length Information Elements */
-};
-
-struct brcm_rateset_le {
- /* # rates in this set */
- __le32 count;
- /* rates in 500kbps units w/hi bit set if basic */
- u8 rates[WL_NUMRATES];
-};
-
-struct brcmf_ssid {
- u32 SSID_len;
- unsigned char SSID[32];
-};
-
-struct brcmf_ssid_le {
- __le32 SSID_len;
- unsigned char SSID[32];
-};
-
-struct brcmf_scan_params_le {
- struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
- u8 bssid[ETH_ALEN]; /* default: bcast */
- s8 bss_type; /* default: any,
- * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
- */
- u8 scan_type; /* flags, 0 use default */
- __le32 nprobes; /* -1 use default, number of probes per channel */
- __le32 active_time; /* -1 use default, dwell time per channel for
- * active scanning
- */
- __le32 passive_time; /* -1 use default, dwell time per channel
- * for passive scanning
- */
- __le32 home_time; /* -1 use default, dwell time for the
- * home channel between channel scans
- */
- __le32 channel_num; /* count of channels and ssids that follow
- *
- * low half is count of channels in
- * channel_list, 0 means default (use all
- * available channels)
- *
- * high half is entries in struct brcmf_ssid
- * array that follows channel_list, aligned for
- * s32 (4 bytes) meaning an odd channel count
- * implies a 2-byte pad between end of
- * channel_list and first ssid
- *
- * if ssid count is zero, single ssid in the
- * fixed parameter portion is assumed, otherwise
- * ssid in the fixed portion is ignored
- */
- __le16 channel_list[1]; /* list of chanspecs */
-};
-
-/* incremental scan struct */
-struct brcmf_iscan_params_le {
- __le32 version;
- __le16 action;
- __le16 scan_duration;
- struct brcmf_scan_params_le params_le;
-};
-
-struct brcmf_scan_results {
- u32 buflen;
- u32 version;
- u32 count;
- struct brcmf_bss_info bss_info[1];
-};
-
-struct brcmf_scan_results_le {
- __le32 buflen;
- __le32 version;
- __le32 count;
- struct brcmf_bss_info bss_info[1];
-};
-
-/* used for association with a specific BSSID and chanspec list */
-struct brcmf_assoc_params_le {
- /* 00:00:00:00:00:00: broadcast scan */
- u8 bssid[ETH_ALEN];
- /* 0: all available channels, otherwise count of chanspecs in
- * chanspec_list */
- __le32 chanspec_num;
- /* list of chanspecs */
- __le16 chanspec_list[1];
-};
-
-/* used for join with or without a specific bssid and channel list */
-struct brcmf_join_params {
- struct brcmf_ssid_le ssid_le;
- struct brcmf_assoc_params_le params_le;
-};
-
-/* size of brcmf_scan_results not including variable length array */
-#define BRCMF_SCAN_RESULTS_FIXED_SIZE \
- (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info))
-
-/* incremental scan results struct */
-struct brcmf_iscan_results {
- union {
- u32 status;
- __le32 status_le;
- };
- union {
- struct brcmf_scan_results results;
- struct brcmf_scan_results_le results_le;
- };
-};
-
-/* size of brcmf_iscan_results not including variable length array */
-#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
- (BRCMF_SCAN_RESULTS_FIXED_SIZE + \
- offsetof(struct brcmf_iscan_results, results))
-
-struct brcmf_wsec_key {
- u32 index; /* key index */
- u32 len; /* key length */
- u8 data[WLAN_MAX_KEY_LEN]; /* key data */
- u32 pad_1[18];
- u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
- u32 flags; /* misc flags */
- u32 pad_2[3];
- u32 iv_initialized; /* has IV been initialized already? */
- u32 pad_3;
- /* Rx IV */
- struct {
- u32 hi; /* upper 32 bits of IV */
- u16 lo; /* lower 16 bits of IV */
- } rxiv;
- u32 pad_4[2];
- u8 ea[ETH_ALEN]; /* per station */
-};
-
-/*
- * dongle requires same struct as above but with fields in little endian order
- */
-struct brcmf_wsec_key_le {
- __le32 index; /* key index */
- __le32 len; /* key length */
- u8 data[WLAN_MAX_KEY_LEN]; /* key data */
- __le32 pad_1[18];
- __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
- __le32 flags; /* misc flags */
- __le32 pad_2[3];
- __le32 iv_initialized; /* has IV been initialized already? */
- __le32 pad_3;
- /* Rx IV */
- struct {
- __le32 hi; /* upper 32 bits of IV */
- __le16 lo; /* lower 16 bits of IV */
- } rxiv;
- __le32 pad_4[2];
- u8 ea[ETH_ALEN]; /* per station */
-};
-
-/* Used to get specific STA parameters */
-struct brcmf_scb_val_le {
- __le32 val;
- u8 ea[ETH_ALEN];
-};
-
-/* channel encoding */
-struct brcmf_channel_info_le {
- __le32 hw_channel;
- __le32 target_channel;
- __le32 scan_channel;
-};
-
-/* Bus independent dongle command */
-struct brcmf_dcmd {
- uint cmd; /* common dongle cmd definition */
- void *buf; /* pointer to user buffer */
- uint len; /* length of user buffer */
- u8 set; /* get or set request (optional) */
- uint used; /* bytes read or written (optional) */
- uint needed; /* bytes needed (optional) */
-};
-
-/* Forward decls for struct brcmf_pub (see below) */
-struct brcmf_bus; /* device bus info */
-struct brcmf_proto; /* device communication protocol info */
-struct brcmf_info; /* device driver info */
-struct brcmf_cfg80211_dev; /* cfg80211 device info */
-
-/* Common structure for module and instance linkage */
-struct brcmf_pub {
- /* Linkage ponters */
- struct brcmf_bus *bus;
- struct brcmf_proto *prot;
- struct brcmf_info *info;
- struct brcmf_cfg80211_dev *config;
-
- /* Internal brcmf items */
- bool up; /* Driver up/down (to OS) */
- bool txoff; /* Transmit flow-controlled */
- enum brcmf_bus_state busstate;
- uint hdrlen; /* Total BRCMF header length (proto + bus) */
- uint maxctl; /* Max size rxctl request from proto to bus */
- uint rxsz; /* Rx buffer size bus module should use */
- u8 wme_dp; /* wme discard priority */
-
- /* Dongle media info */
- bool iswl; /* Dongle-resident driver is wl */
- unsigned long drv_version; /* Version of dongle-resident driver */
- u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
- struct dngl_stats dstats; /* Stats for dongle-based data */
-
- /* Additional stats for the bus level */
-
- /* Data packets sent to dongle */
- unsigned long tx_packets;
- /* Multicast data packets sent to dongle */
- unsigned long tx_multicast;
- /* Errors in sending data to dongle */
- unsigned long tx_errors;
- /* Control packets sent to dongle */
- unsigned long tx_ctlpkts;
- /* Errors sending control frames to dongle */
- unsigned long tx_ctlerrs;
- /* Packets sent up the network interface */
- unsigned long rx_packets;
- /* Multicast packets sent up the network interface */
- unsigned long rx_multicast;
- /* Errors processing rx data packets */
- unsigned long rx_errors;
- /* Control frames processed from dongle */
- unsigned long rx_ctlpkts;
-
- /* Errors in processing rx control frames */
- unsigned long rx_ctlerrs;
- /* Packets dropped locally (no memory) */
- unsigned long rx_dropped;
- /* Packets flushed due to unscheduled sendup thread */
- unsigned long rx_flushed;
- /* Number of times dpc scheduled by watchdog timer */
- unsigned long wd_dpc_sched;
-
- /* Number of packets where header read-ahead was used. */
- unsigned long rx_readahead_cnt;
- /* Number of tx packets we had to realloc for headroom */
- unsigned long tx_realloc;
- /* Number of flow control pkts recvd */
- unsigned long fc_packets;
-
- /* Last error return */
- int bcmerror;
- uint tickcnt;
-
- /* Last error from dongle */
- int dongle_error;
-
- /* Suspend disable flag flag */
- int suspend_disable_flag; /* "1" to disable all extra powersaving
- during suspend */
- int in_suspend; /* flag set to 1 when early suspend called */
- int dtim_skip; /* dtim skip , default 0 means wake each dtim */
-
- /* Pkt filter defination */
- char *pktfilter[100];
- int pktfilter_count;
-
- u8 country_code[BRCM_CNTRY_BUF_SZ];
- char eventmask[BRCMF_EVENTING_MASK_LEN];
-
-};
-
-struct brcmf_if_event {
- u8 ifidx;
- u8 action;
- u8 flags;
- u8 bssidx;
-};
-
-struct bcmevent_name {
- uint event;
- const char *name;
-};
-
-extern const struct bcmevent_name bcmevent_names[];
-
-/* Indication from bus module regarding presence/insertion of dongle.
- * Return struct brcmf_pub pointer, used as handle to OS module in later calls.
- * Returned structure should have bus and prot pointers filled in.
- * bus_hdrlen specifies required headroom for bus module header.
- */
-extern struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus,
- uint bus_hdrlen);
-extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx);
-extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
-
-extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
-
-/* Indication from bus module regarding removal/absence of dongle */
-extern void brcmf_detach(struct brcmf_pub *drvr);
-
-/* Indication from bus module to change flow-control state */
-extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on);
-
-extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
- struct sk_buff *pkt, int prec);
-
-/* Receive frame for delivery to OS. Callee disposes of rxp. */
-extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
- struct sk_buff *rxp, int numpkt);
-
-/* Return pointer to interface name */
-extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
-
-/* Notify tx completion */
-extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp,
- bool success);
-
-/* Query dongle */
-extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
- uint cmd, void *buf, uint len);
-
-/* OS independent layer functions */
-extern int brcmf_os_proto_block(struct brcmf_pub *drvr);
-extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr);
-#ifdef BCMDBG
-extern int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size);
-#endif /* BCMDBG */
-
-extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name);
-extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx,
- void *pktdata, struct brcmf_event_msg *,
- void **data_ptr);
-
-extern void brcmf_c_init(void);
-
-extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx,
- struct net_device *ndev, char *name, u8 *mac_addr,
- u32 flags, u8 bssidx);
-extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx);
-
-/* Send packet to dongle via data channel */
-extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
- struct sk_buff *pkt);
-
-extern int brcmf_bus_start(struct brcmf_pub *drvr);
-
-extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
-extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
- int enable, int master_mode);
-
-#define BRCMF_DCMD_SMLEN 256 /* "small" cmd buffer required */
-#define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */
-#define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */
-
-/* message levels */
-#define BRCMF_ERROR_VAL 0x0001
-#define BRCMF_TRACE_VAL 0x0002
-#define BRCMF_INFO_VAL 0x0004
-#define BRCMF_DATA_VAL 0x0008
-#define BRCMF_CTL_VAL 0x0010
-#define BRCMF_TIMER_VAL 0x0020
-#define BRCMF_HDRS_VAL 0x0040
-#define BRCMF_BYTES_VAL 0x0080
-#define BRCMF_INTR_VAL 0x0100
-#define BRCMF_GLOM_VAL 0x0400
-#define BRCMF_EVENT_VAL 0x0800
-#define BRCMF_BTA_VAL 0x1000
-#define BRCMF_ISCAN_VAL 0x2000
-
-/* Enter idle immediately (no timeout) */
-#define BRCMF_IDLE_IMMEDIATE (-1)
-#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
- when idle */
-#define BRCMF_IDLE_INTERVAL 1
-
-#endif /* _BRCMF_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h
deleted file mode 100644
index a249407c9a1b..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _BRCMF_BUS_H_
-#define _BRCMF_BUS_H_
-
-/* Packet alignment for most efficient SDIO (can change based on platform) */
-#define BRCMF_SDALIGN (1 << 6)
-
-/* watchdog polling interval in ms */
-#define BRCMF_WD_POLL_MS 10
-
-/*
- * Exported from brcmf bus module (brcmf_usb, brcmf_sdio)
- */
-
-/* Indicate (dis)interest in finding dongles. */
-extern int brcmf_bus_register(void);
-extern void brcmf_bus_unregister(void);
-
-/* obtain linux device object providing bus function */
-extern struct device *brcmf_bus_get_device(struct brcmf_bus *bus);
-
-/* Stop bus module: clear pending frames, disable data flow */
-extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus);
-
-/* Initialize bus module: prepare for communication w/dongle */
-extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr);
-
-/* Send a data frame to the dongle. Callee disposes of txp. */
-extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp);
-
-/* Send/receive a control message to/from the dongle.
- * Expects caller to enforce a single outstanding transaction.
- */
-extern int
-brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
-
-extern int
-brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
-
-extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick);
-
-#endif /* _BRCMF_BUS_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
deleted file mode 100644
index e34c5c3d1d55..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*******************************************************************************
- * Communicates with the dongle by using dcmd codes.
- * For certain dcmd codes, the dongle interprets string data from the host.
- ******************************************************************************/
-
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/sched.h>
-#include <defs.h>
-
-#include <brcmu_utils.h>
-#include <brcmu_wifi.h>
-
-#include "dhd.h"
-#include "dhd_proto.h"
-#include "dhd_bus.h"
-#include "dhd_dbg.h"
-
-struct brcmf_proto_cdc_dcmd {
- __le32 cmd; /* dongle command value */
- __le32 len; /* lower 16: output buflen;
- * upper 16: input buflen (excludes header) */
- __le32 flags; /* flag defns given below */
- __le32 status; /* status code returned from the device */
-};
-
-/* Max valid buffer size that can be sent to the dongle */
-#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
-
-/* CDC flag definitions */
-#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */
-#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
-#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */
-#define CDC_DCMD_IF_SHIFT 12
-#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
-#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
-#define CDC_DCMD_ID(flags) \
- (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
-
-/*
- * BDC header - Broadcom specific extension of CDC.
- * Used on data packets to convey priority across USB.
- */
-#define BDC_HEADER_LEN 4
-#define BDC_PROTO_VER 1 /* Protocol version */
-#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
-#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
-#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
-#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
-#define BDC_PRIORITY_MASK 0x7
-#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
-#define BDC_FLAG2_IF_SHIFT 0
-
-#define BDC_GET_IF_IDX(hdr) \
- ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
-#define BDC_SET_IF_IDX(hdr, idx) \
- ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
- ((idx) << BDC_FLAG2_IF_SHIFT)))
-
-struct brcmf_proto_bdc_header {
- u8 flags;
- u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */
- u8 flags2;
- u8 rssi;
-};
-
-
-#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
-#define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE
- * (amount of header tha might be added)
- * plus any space that might be needed
- * for alignment padding.
- */
-#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for
- * round off at the end of buffer
- */
-
-struct brcmf_proto {
- u16 reqid;
- u8 pending;
- u32 lastcmd;
- u8 bus_header[BUS_HEADER_LEN];
- struct brcmf_proto_cdc_dcmd msg;
- unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
-};
-
-static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
-{
- struct brcmf_proto *prot = drvr->prot;
- int len = le32_to_cpu(prot->msg.len) +
- sizeof(struct brcmf_proto_cdc_dcmd);
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* NOTE : cdc->msg.len holds the desired length of the buffer to be
- * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
- * is actually sent to the dongle
- */
- if (len > CDC_MAX_MSG_SIZE)
- len = CDC_MAX_MSG_SIZE;
-
- /* Send request */
- return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg,
- len);
-}
-
-static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
-{
- int ret;
- struct brcmf_proto *prot = drvr->prot;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- do {
- ret = brcmf_sdbrcm_bus_rxctl(drvr->bus,
- (unsigned char *)&prot->msg,
- len + sizeof(struct brcmf_proto_cdc_dcmd));
- if (ret < 0)
- break;
- } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
-
- return ret;
-}
-
-int
-brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
- void *buf, uint len)
-{
- struct brcmf_proto *prot = drvr->prot;
- struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
- void *info;
- int ret = 0, retries = 0;
- u32 id, flags;
-
- brcmf_dbg(TRACE, "Enter\n");
- brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
-
- /* Respond "bcmerror" and "bcmerrorstr" with local cache */
- if (cmd == BRCMF_C_GET_VAR && buf) {
- if (!strcmp((char *)buf, "bcmerrorstr")) {
- strncpy((char *)buf, "bcm_error",
- BCME_STRLEN);
- goto done;
- } else if (!strcmp((char *)buf, "bcmerror")) {
- *(int *)buf = drvr->dongle_error;
- goto done;
- }
- }
-
- memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
-
- msg->cmd = cpu_to_le32(cmd);
- msg->len = cpu_to_le32(len);
- flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
- flags = (flags & ~CDC_DCMD_IF_MASK) |
- (ifidx << CDC_DCMD_IF_SHIFT);
- msg->flags = cpu_to_le32(flags);
-
- if (buf)
- memcpy(prot->buf, buf, len);
-
- ret = brcmf_proto_cdc_msg(drvr);
- if (ret < 0) {
- brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n",
- ret);
- goto done;
- }
-
-retry:
- /* wait for interrupt and get first fragment */
- ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
- if (ret < 0)
- goto done;
-
- flags = le32_to_cpu(msg->flags);
- id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
-
- if ((id < prot->reqid) && (++retries < RETRIES))
- goto retry;
- if (id != prot->reqid) {
- brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
- brcmf_ifname(drvr, ifidx), id, prot->reqid);
- ret = -EINVAL;
- goto done;
- }
-
- /* Check info buffer */
- info = (void *)&msg[1];
-
- /* Copy info buffer */
- if (buf) {
- if (ret < (int)len)
- len = ret;
- memcpy(buf, info, len);
- }
-
- /* Check the ERROR flag */
- if (flags & CDC_DCMD_ERROR) {
- ret = le32_to_cpu(msg->status);
- /* Cache error from dongle */
- drvr->dongle_error = ret;
- }
-
-done:
- return ret;
-}
-
-int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
- void *buf, uint len)
-{
- struct brcmf_proto *prot = drvr->prot;
- struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
- int ret = 0;
- u32 flags, id;
-
- brcmf_dbg(TRACE, "Enter\n");
- brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
-
- memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
-
- msg->cmd = cpu_to_le32(cmd);
- msg->len = cpu_to_le32(len);
- flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
- flags = (flags & ~CDC_DCMD_IF_MASK) |
- (ifidx << CDC_DCMD_IF_SHIFT);
- msg->flags = cpu_to_le32(flags);
-
- if (buf)
- memcpy(prot->buf, buf, len);
-
- ret = brcmf_proto_cdc_msg(drvr);
- if (ret < 0)
- goto done;
-
- ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
- if (ret < 0)
- goto done;
-
- flags = le32_to_cpu(msg->flags);
- id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
-
- if (id != prot->reqid) {
- brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
- brcmf_ifname(drvr, ifidx), id, prot->reqid);
- ret = -EINVAL;
- goto done;
- }
-
- /* Check the ERROR flag */
- if (flags & CDC_DCMD_ERROR) {
- ret = le32_to_cpu(msg->status);
- /* Cache error from dongle */
- drvr->dongle_error = ret;
- }
-
-done:
- return ret;
-}
-
-int
-brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
- int len)
-{
- struct brcmf_proto *prot = drvr->prot;
- int ret = -1;
-
- if (drvr->busstate == BRCMF_BUS_DOWN) {
- brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
- return ret;
- }
- brcmf_os_proto_block(drvr);
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (len > BRCMF_DCMD_MAXLEN)
- goto done;
-
- if (prot->pending == true) {
- brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
- dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
- (unsigned long)prot->lastcmd);
- if (dcmd->cmd == BRCMF_C_SET_VAR ||
- dcmd->cmd == BRCMF_C_GET_VAR)
- brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
-
- goto done;
- }
-
- prot->pending = true;
- prot->lastcmd = dcmd->cmd;
- if (dcmd->set)
- ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
- dcmd->buf, len);
- else {
- ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
- dcmd->buf, len);
- if (ret > 0)
- dcmd->used = ret -
- sizeof(struct brcmf_proto_cdc_dcmd);
- }
-
- if (ret >= 0)
- ret = 0;
- else {
- struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
- /* len == needed when set/query fails from dongle */
- dcmd->needed = le32_to_cpu(msg->len);
- }
-
- /* Intercept the wme_dp dongle cmd here */
- if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
- !strcmp(dcmd->buf, "wme_dp")) {
- int slen;
- __le32 val = 0;
-
- slen = strlen("wme_dp") + 1;
- if (len >= (int)(slen + sizeof(int)))
- memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
- drvr->wme_dp = (u8) le32_to_cpu(val);
- }
-
- prot->pending = false;
-
-done:
- brcmf_os_proto_unblock(drvr);
-
- return ret;
-}
-
-static bool pkt_sum_needed(struct sk_buff *skb)
-{
- return skb->ip_summed == CHECKSUM_PARTIAL;
-}
-
-static void pkt_set_sum_good(struct sk_buff *skb, bool x)
-{
- skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
-}
-
-void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
- struct sk_buff *pktbuf)
-{
- struct brcmf_proto_bdc_header *h;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Push BDC header used to convey priority for buses that don't */
-
- skb_push(pktbuf, BDC_HEADER_LEN);
-
- h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
-
- h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
- if (pkt_sum_needed(pktbuf))
- h->flags |= BDC_FLAG_SUM_NEEDED;
-
- h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
- h->flags2 = 0;
- h->rssi = 0;
- BDC_SET_IF_IDX(h, ifidx);
-}
-
-int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx,
- struct sk_buff *pktbuf)
-{
- struct brcmf_proto_bdc_header *h;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Pop BDC header used to convey priority for buses that don't */
-
- if (pktbuf->len < BDC_HEADER_LEN) {
- brcmf_dbg(ERROR, "rx data too short (%d < %d)\n",
- pktbuf->len, BDC_HEADER_LEN);
- return -EBADE;
- }
-
- h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
-
- *ifidx = BDC_GET_IF_IDX(h);
- if (*ifidx >= BRCMF_MAX_IFS) {
- brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx);
- return -EBADE;
- }
-
- if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
- BDC_PROTO_VER) {
- brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n",
- brcmf_ifname(drvr, *ifidx), h->flags);
- return -EBADE;
- }
-
- if (h->flags & BDC_FLAG_SUM_GOOD) {
- brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
- brcmf_ifname(drvr, *ifidx), h->flags);
- pkt_set_sum_good(pktbuf, true);
- }
-
- pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
-
- skb_pull(pktbuf, BDC_HEADER_LEN);
-
- return 0;
-}
-
-int brcmf_proto_attach(struct brcmf_pub *drvr)
-{
- struct brcmf_proto *cdc;
-
- cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
- if (!cdc)
- goto fail;
-
- /* ensure that the msg buf directly follows the cdc msg struct */
- if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
- brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n");
- goto fail;
- }
-
- drvr->prot = cdc;
- drvr->hdrlen += BDC_HEADER_LEN;
- drvr->maxctl = BRCMF_DCMD_MAXLEN +
- sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
- return 0;
-
-fail:
- kfree(cdc);
- return -ENOMEM;
-}
-
-/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
-void brcmf_proto_detach(struct brcmf_pub *drvr)
-{
- kfree(drvr->prot);
- drvr->prot = NULL;
-}
-
-void brcmf_proto_dstats(struct brcmf_pub *drvr)
-{
- /* No stats from dongle added yet, copy bus stats */
- drvr->dstats.tx_packets = drvr->tx_packets;
- drvr->dstats.tx_errors = drvr->tx_errors;
- drvr->dstats.rx_packets = drvr->rx_packets;
- drvr->dstats.rx_errors = drvr->rx_errors;
- drvr->dstats.rx_dropped = drvr->rx_dropped;
- drvr->dstats.multicast = drvr->rx_multicast;
- return;
-}
-
-int brcmf_proto_init(struct brcmf_pub *drvr)
-{
- int ret = 0;
- char buf[128];
-
- brcmf_dbg(TRACE, "Enter\n");
-
- brcmf_os_proto_block(drvr);
-
- /* Get the device MAC address */
- strcpy(buf, "cur_etheraddr");
- ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR,
- buf, sizeof(buf));
- if (ret < 0) {
- brcmf_os_proto_unblock(drvr);
- return ret;
- }
- memcpy(drvr->mac, buf, ETH_ALEN);
-
- brcmf_os_proto_unblock(drvr);
-
- ret = brcmf_c_preinit_dcmds(drvr);
-
- /* Always assumes wl for now */
- drvr->iswl = true;
-
- return ret;
-}
-
-void brcmf_proto_stop(struct brcmf_pub *drvr)
-{
- /* Nothing to do for CDC */
-}
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c
deleted file mode 100644
index 4075fd74dd92..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/netdevice.h>
-#include <asm/unaligned.h>
-#include <defs.h>
-#include <brcmu_wifi.h>
-#include <brcmu_utils.h>
-#include "dhd.h"
-#include "dhd_bus.h"
-#include "dhd_proto.h"
-#include "dhd_dbg.h"
-
-#define BRCM_OUI "\x00\x10\x18"
-#define DOT11_OUI_LEN 3
-#define BCMILCP_BCM_SUBTYPE_EVENT 1
-#define PKTFILTER_BUF_SIZE 2048
-#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
-
-int brcmf_msg_level;
-
-#define MSGTRACE_VERSION 1
-
-#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter, u)
-#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
- offsetof(struct brcmf_pkt_filter_pattern, mask_and_pattern)
-
-#ifdef BCMDBG
-static const char brcmf_version[] =
- "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
- __DATE__ " at " __TIME__;
-#else
-static const char brcmf_version[] =
- "Dongle Host Driver, version " BRCMF_VERSION_STR;
-#endif
-
-/* Message trace header */
-struct msgtrace_hdr {
- u8 version;
- u8 spare;
- __be16 len; /* Len of the trace */
- __be32 seqnum; /* Sequence number of message. Useful
- * if the messsage has been lost
- * because of DMA error or a bus reset
- * (ex: SDIO Func2)
- */
- __be32 discarded_bytes; /* Number of discarded bytes because of
- trace overflow */
- __be32 discarded_printf; /* Number of discarded printf
- because of trace overflow */
-} __packed;
-
-void brcmf_c_init(void)
-{
- /* Init global variables at run-time, not as part of the declaration.
- * This is required to support init/de-init of the driver.
- * Initialization
- * of globals as part of the declaration results in non-deterministic
- * behaviour since the value of the globals may be different on the
- * first time that the driver is initialized vs subsequent
- * initializations.
- */
- brcmf_msg_level = BRCMF_ERROR_VAL;
-}
-
-bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
- struct sk_buff *pkt, int prec)
-{
- struct sk_buff *p;
- int eprec = -1; /* precedence to evict from */
- bool discard_oldest;
-
- /* Fast case, precedence queue is not full and we are also not
- * exceeding total queue length
- */
- if (!pktq_pfull(q, prec) && !pktq_full(q)) {
- brcmu_pktq_penq(q, prec, pkt);
- return true;
- }
-
- /* Determine precedence from which to evict packet, if any */
- if (pktq_pfull(q, prec))
- eprec = prec;
- else if (pktq_full(q)) {
- p = brcmu_pktq_peek_tail(q, &eprec);
- if (eprec > prec)
- return false;
- }
-
- /* Evict if needed */
- if (eprec >= 0) {
- /* Detect queueing to unconfigured precedence */
- discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec);
- if (eprec == prec && !discard_oldest)
- return false; /* refuse newer (incoming) packet */
- /* Evict packet according to discard policy */
- p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
- brcmu_pktq_pdeq_tail(q, eprec);
- if (p == NULL)
- brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n",
- discard_oldest);
-
- brcmu_pkt_buf_free_skb(p);
- }
-
- /* Enqueue */
- p = brcmu_pktq_penq(q, prec, pkt);
- if (p == NULL)
- brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n");
-
- return p != NULL;
-}
-
-#ifdef BCMDBG
-static void
-brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
-{
- uint i, status, reason;
- bool group = false, flush_txq = false, link = false;
- char *auth_str, *event_name;
- unsigned char *buf;
- char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
- static struct {
- uint event;
- char *event_name;
- } event_names[] = {
- {
- BRCMF_E_SET_SSID, "SET_SSID"}, {
- BRCMF_E_JOIN, "JOIN"}, {
- BRCMF_E_START, "START"}, {
- BRCMF_E_AUTH, "AUTH"}, {
- BRCMF_E_AUTH_IND, "AUTH_IND"}, {
- BRCMF_E_DEAUTH, "DEAUTH"}, {
- BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
- BRCMF_E_ASSOC, "ASSOC"}, {
- BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
- BRCMF_E_REASSOC, "REASSOC"}, {
- BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
- BRCMF_E_DISASSOC, "DISASSOC"}, {
- BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
- BRCMF_E_QUIET_START, "START_QUIET"}, {
- BRCMF_E_QUIET_END, "END_QUIET"}, {
- BRCMF_E_BEACON_RX, "BEACON_RX"}, {
- BRCMF_E_LINK, "LINK"}, {
- BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
- BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
- BRCMF_E_ROAM, "ROAM"}, {
- BRCMF_E_TXFAIL, "TXFAIL"}, {
- BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
- BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
- BRCMF_E_PRUNE, "PRUNE"}, {
- BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
- BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
- BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
- BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
- BRCMF_E_DELTS_IND, "DELTS_IND"}, {
- BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
- BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
- BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
- BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
- BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
- BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
- BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
- BRCMF_E_JOIN_START, "JOIN_START"}, {
- BRCMF_E_ROAM_START, "ROAM_START"}, {
- BRCMF_E_ASSOC_START, "ASSOC_START"}, {
- BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
- BRCMF_E_RADIO, "RADIO"}, {
- BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
- BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
- BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
- BRCMF_E_PSK_SUP, "PSK_SUP"}, {
- BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
- BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
- BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
- BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
- BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
- BRCMF_E_TRACE, "TRACE"}, {
- BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
- BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
- BRCMF_E_IF, "IF"}, {
- BRCMF_E_RSSI, "RSSI"}, {
- BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
- };
- uint event_type, flags, auth_type, datalen;
- static u32 seqnum_prev;
- struct msgtrace_hdr hdr;
- u32 nblost;
- char *s, *p;
-
- event_type = be32_to_cpu(event->event_type);
- flags = be16_to_cpu(event->flags);
- status = be32_to_cpu(event->status);
- reason = be32_to_cpu(event->reason);
- auth_type = be32_to_cpu(event->auth_type);
- datalen = be32_to_cpu(event->datalen);
- /* debug dump of event messages */
- sprintf(eabuf, "%pM", event->addr);
-
- event_name = "UNKNOWN";
- for (i = 0; i < ARRAY_SIZE(event_names); i++) {
- if (event_names[i].event == event_type)
- event_name = event_names[i].event_name;
- }
-
- brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type);
- brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
- flags, status, reason, auth_type, eabuf);
-
- if (flags & BRCMF_EVENT_MSG_LINK)
- link = true;
- if (flags & BRCMF_EVENT_MSG_GROUP)
- group = true;
- if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
- flush_txq = true;
-
- switch (event_type) {
- case BRCMF_E_START:
- case BRCMF_E_DEAUTH:
- case BRCMF_E_DISASSOC:
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
- break;
-
- case BRCMF_E_ASSOC_IND:
- case BRCMF_E_REASSOC_IND:
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
- break;
-
- case BRCMF_E_ASSOC:
- case BRCMF_E_REASSOC:
- if (status == BRCMF_E_STATUS_SUCCESS)
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n",
- event_name, eabuf);
- else if (status == BRCMF_E_STATUS_TIMEOUT)
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n",
- event_name, eabuf);
- else if (status == BRCMF_E_STATUS_FAIL)
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
- event_name, eabuf, (int)reason);
- else
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n",
- event_name, eabuf, (int)status);
- break;
-
- case BRCMF_E_DEAUTH_IND:
- case BRCMF_E_DISASSOC_IND:
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n",
- event_name, eabuf, (int)reason);
- break;
-
- case BRCMF_E_AUTH:
- case BRCMF_E_AUTH_IND:
- if (auth_type == WLAN_AUTH_OPEN)
- auth_str = "Open System";
- else if (auth_type == WLAN_AUTH_SHARED_KEY)
- auth_str = "Shared Key";
- else {
- sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
- auth_str = err_msg;
- }
- if (event_type == BRCMF_E_AUTH_IND)
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n",
- event_name, eabuf, auth_str);
- else if (status == BRCMF_E_STATUS_SUCCESS)
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n",
- event_name, eabuf, auth_str);
- else if (status == BRCMF_E_STATUS_TIMEOUT)
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
- event_name, eabuf, auth_str);
- else if (status == BRCMF_E_STATUS_FAIL) {
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n",
- event_name, eabuf, auth_str, (int)reason);
- }
-
- break;
-
- case BRCMF_E_JOIN:
- case BRCMF_E_ROAM:
- case BRCMF_E_SET_SSID:
- if (status == BRCMF_E_STATUS_SUCCESS)
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n",
- event_name, eabuf);
- else if (status == BRCMF_E_STATUS_FAIL)
- brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name);
- else if (status == BRCMF_E_STATUS_NO_NETWORKS)
- brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n",
- event_name);
- else
- brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n",
- event_name, (int)status);
- break;
-
- case BRCMF_E_BEACON_RX:
- if (status == BRCMF_E_STATUS_SUCCESS)
- brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name);
- else if (status == BRCMF_E_STATUS_FAIL)
- brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name);
- else
- brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n",
- event_name, status);
- break;
-
- case BRCMF_E_LINK:
- brcmf_dbg(EVENT, "MACEVENT: %s %s\n",
- event_name, link ? "UP" : "DOWN");
- break;
-
- case BRCMF_E_MIC_ERROR:
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
- event_name, eabuf, group, flush_txq);
- break;
-
- case BRCMF_E_ICV_ERROR:
- case BRCMF_E_UNICAST_DECODE_ERROR:
- case BRCMF_E_MULTICAST_DECODE_ERROR:
- brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
- break;
-
- case BRCMF_E_TXFAIL:
- brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf);
- break;
-
- case BRCMF_E_SCAN_COMPLETE:
- case BRCMF_E_PMKID_CACHE:
- brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
- break;
-
- case BRCMF_E_PFN_NET_FOUND:
- case BRCMF_E_PFN_NET_LOST:
- case BRCMF_E_PFN_SCAN_COMPLETE:
- brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name);
- break;
-
- case BRCMF_E_PSK_SUP:
- case BRCMF_E_PRUNE:
- brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n",
- event_name, (int)status, (int)reason);
- break;
-
- case BRCMF_E_TRACE:
- buf = (unsigned char *) event_data;
- memcpy(&hdr, buf, sizeof(struct msgtrace_hdr));
-
- if (hdr.version != MSGTRACE_VERSION) {
- brcmf_dbg(ERROR,
- "MACEVENT: %s [unsupported version --> brcmf"
- " version:%d dongle version:%d]\n",
- event_name, MSGTRACE_VERSION, hdr.version);
- /* Reset datalen to avoid display below */
- datalen = 0;
- break;
- }
-
- /* There are 2 bytes available at the end of data */
- *(buf + sizeof(struct msgtrace_hdr)
- + be16_to_cpu(hdr.len)) = '\0';
-
- if (be32_to_cpu(hdr.discarded_bytes)
- || be32_to_cpu(hdr.discarded_printf))
- brcmf_dbg(ERROR,
- "WLC_E_TRACE: [Discarded traces in dongle -->"
- " discarded_bytes %d discarded_printf %d]\n",
- be32_to_cpu(hdr.discarded_bytes),
- be32_to_cpu(hdr.discarded_printf));
-
- nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
- if (nblost > 0)
- brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum "
- " %d nblost %d\n", be32_to_cpu(hdr.seqnum),
- nblost);
- seqnum_prev = be32_to_cpu(hdr.seqnum);
-
- /* Display the trace buffer. Advance from \n to \n to
- * avoid display big
- * printf (issue with Linux printk )
- */
- p = (char *)&buf[sizeof(struct msgtrace_hdr)];
- while ((s = strstr(p, "\n")) != NULL) {
- *s = '\0';
- printk(KERN_DEBUG"%s\n", p);
- p = s + 1;
- }
- printk(KERN_DEBUG "%s\n", p);
-
- /* Reset datalen to avoid display below */
- datalen = 0;
- break;
-
- case BRCMF_E_RSSI:
- brcmf_dbg(EVENT, "MACEVENT: %s %d\n",
- event_name, be32_to_cpu(*((__be32 *)event_data)));
- break;
-
- default:
- brcmf_dbg(EVENT,
- "MACEVENT: %s %d, MAC %s, status %d, reason %d, "
- "auth %d\n", event_name, event_type, eabuf,
- (int)status, (int)reason, (int)auth_type);
- break;
- }
-
- /* show any appended data */
- if (datalen) {
- buf = (unsigned char *) event_data;
- brcmf_dbg(EVENT, " data (%d) : ", datalen);
- for (i = 0; i < datalen; i++)
- brcmf_dbg(EVENT, " 0x%02x ", *buf++);
- brcmf_dbg(EVENT, "\n");
- }
-}
-#endif /* BCMDBG */
-
-int
-brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata,
- struct brcmf_event_msg *event, void **data_ptr)
-{
- /* check whether packet is a BRCM event pkt */
- struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
- struct brcmf_if_event *ifevent;
- char *event_data;
- u32 type, status;
- u16 flags;
- int evlen;
-
- if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) {
- brcmf_dbg(ERROR, "mismatched OUI, bailing\n");
- return -EBADE;
- }
-
- /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
- if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) !=
- BCMILCP_BCM_SUBTYPE_EVENT) {
- brcmf_dbg(ERROR, "mismatched subtype, bailing\n");
- return -EBADE;
- }
-
- *data_ptr = &pvt_data[1];
- event_data = *data_ptr;
-
- /* memcpy since BRCM event pkt may be unaligned. */
- memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg));
-
- type = get_unaligned_be32(&event->event_type);
- flags = get_unaligned_be16(&event->flags);
- status = get_unaligned_be32(&event->status);
- evlen = get_unaligned_be32(&event->datalen) +
- sizeof(struct brcmf_event);
-
- switch (type) {
- case BRCMF_E_IF:
- ifevent = (struct brcmf_if_event *) event_data;
- brcmf_dbg(TRACE, "if event\n");
-
- if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) {
- if (ifevent->action == BRCMF_E_IF_ADD)
- brcmf_add_if(drvr_priv, ifevent->ifidx, NULL,
- event->ifname,
- pvt_data->eth.h_dest,
- ifevent->flags, ifevent->bssidx);
- else
- brcmf_del_if(drvr_priv, ifevent->ifidx);
- } else {
- brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n",
- ifevent->ifidx, event->ifname);
- }
-
- /* send up the if event: btamp user needs it */
- *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname);
- break;
-
- /* These are what external supplicant/authenticator wants */
- case BRCMF_E_LINK:
- case BRCMF_E_ASSOC_IND:
- case BRCMF_E_REASSOC_IND:
- case BRCMF_E_DISASSOC_IND:
- case BRCMF_E_MIC_ERROR:
- default:
- /* Fall through: this should get _everything_ */
-
- *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname);
- brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n",
- type, flags, status);
-
- /* put it back to BRCMF_E_NDIS_LINK */
- if (type == BRCMF_E_NDIS_LINK) {
- u32 temp1;
- __be32 temp2;
-
- temp1 = get_unaligned_be32(&event->event_type);
- brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n",
- temp1);
-
- temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK);
- memcpy((void *)(&pvt_data->msg.event_type), &temp2,
- sizeof(pvt_data->msg.event_type));
- }
- break;
- }
-
-#ifdef BCMDBG
- brcmf_c_show_host_event(event, event_data);
-#endif /* BCMDBG */
-
- return 0;
-}
-
-/* Convert user's input in hex pattern to byte-size mask */
-static int brcmf_c_pattern_atoh(char *src, char *dst)
-{
- int i;
- if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
- brcmf_dbg(ERROR, "Mask invalid format. Needs to start with 0x\n");
- return -EINVAL;
- }
- src = src + 2; /* Skip past 0x */
- if (strlen(src) % 2 != 0) {
- brcmf_dbg(ERROR, "Mask invalid format. Length must be even.\n");
- return -EINVAL;
- }
- for (i = 0; *src != '\0'; i++) {
- unsigned long res;
- char num[3];
- strncpy(num, src, 2);
- num[2] = '\0';
- if (kstrtoul(num, 16, &res))
- return -EINVAL;
- dst[i] = (u8)res;
- src += 2;
- }
- return i;
-}
-
-void
-brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
- int master_mode)
-{
- unsigned long res;
- char *argv[8];
- int i = 0;
- const char *str;
- int buf_len;
- int str_len;
- char *arg_save = NULL, *arg_org = NULL;
- int rc;
- char buf[128];
- struct brcmf_pkt_filter_enable enable_parm;
- struct brcmf_pkt_filter_enable *pkt_filterp;
-
- arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
- if (!arg_save)
- goto fail;
-
- arg_org = arg_save;
- memcpy(arg_save, arg, strlen(arg) + 1);
-
- argv[i] = strsep(&arg_save, " ");
-
- i = 0;
- if (NULL == argv[i]) {
- brcmf_dbg(ERROR, "No args provided\n");
- goto fail;
- }
-
- str = "pkt_filter_enable";
- str_len = strlen(str);
- strncpy(buf, str, str_len);
- buf[str_len] = '\0';
- buf_len = str_len + 1;
-
- pkt_filterp = (struct brcmf_pkt_filter_enable *) (buf + str_len + 1);
-
- /* Parse packet filter id. */
- enable_parm.id = 0;
- if (!kstrtoul(argv[i], 0, &res))
- enable_parm.id = (u32)res;
-
- /* Parse enable/disable value. */
- enable_parm.enable = enable;
-
- buf_len += sizeof(enable_parm);
- memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
-
- /* Enable/disable the specified filter. */
- rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
- rc = rc >= 0 ? 0 : rc;
- if (rc)
- brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
- arg, rc);
- else
- brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
-
- /* Contorl the master mode */
- brcmu_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf,
- sizeof(buf));
- rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
- sizeof(buf));
- rc = rc >= 0 ? 0 : rc;
- if (rc)
- brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
- arg, rc);
-
-fail:
- kfree(arg_org);
-}
-
-void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
-{
- const char *str;
- struct brcmf_pkt_filter pkt_filter;
- struct brcmf_pkt_filter *pkt_filterp;
- unsigned long res;
- int buf_len;
- int str_len;
- int rc;
- u32 mask_size;
- u32 pattern_size;
- char *argv[8], *buf = NULL;
- int i = 0;
- char *arg_save = NULL, *arg_org = NULL;
-
- arg_save = kstrdup(arg, GFP_ATOMIC);
- if (!arg_save)
- goto fail;
-
- arg_org = arg_save;
-
- buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
- if (!buf)
- goto fail;
-
- argv[i] = strsep(&arg_save, " ");
- while (argv[i++])
- argv[i] = strsep(&arg_save, " ");
-
- i = 0;
- if (NULL == argv[i]) {
- brcmf_dbg(ERROR, "No args provided\n");
- goto fail;
- }
-
- str = "pkt_filter_add";
- strcpy(buf, str);
- str_len = strlen(str);
- buf_len = str_len + 1;
-
- pkt_filterp = (struct brcmf_pkt_filter *) (buf + str_len + 1);
-
- /* Parse packet filter id. */
- pkt_filter.id = 0;
- if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.id = (u32)res;
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Polarity not provided\n");
- goto fail;
- }
-
- /* Parse filter polarity. */
- pkt_filter.negate_match = 0;
- if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.negate_match = (u32)res;
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Filter type not provided\n");
- goto fail;
- }
-
- /* Parse filter type. */
- pkt_filter.type = 0;
- if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.type = (u32)res;
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Offset not provided\n");
- goto fail;
- }
-
- /* Parse pattern filter offset. */
- pkt_filter.u.pattern.offset = 0;
- if (!kstrtoul(argv[i], 0, &res))
- pkt_filter.u.pattern.offset = (u32)res;
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Bitmask not provided\n");
- goto fail;
- }
-
- /* Parse pattern filter mask. */
- mask_size =
- brcmf_c_pattern_atoh
- (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
-
- if (NULL == argv[++i]) {
- brcmf_dbg(ERROR, "Pattern not provided\n");
- goto fail;
- }
-
- /* Parse pattern filter pattern. */
- pattern_size =
- brcmf_c_pattern_atoh(argv[i],
- (char *)&pkt_filterp->u.pattern.
- mask_and_pattern[mask_size]);
-
- if (mask_size != pattern_size) {
- brcmf_dbg(ERROR, "Mask and pattern not the same size\n");
- goto fail;
- }
-
- pkt_filter.u.pattern.size_bytes = mask_size;
- buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
- buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
-
- /* Keep-alive attributes are set in local
- * variable (keep_alive_pkt), and
- ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
- ** guarantee that the buffer is properly aligned.
- */
- memcpy((char *)pkt_filterp,
- &pkt_filter,
- BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);
-
- rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
- rc = rc >= 0 ? 0 : rc;
-
- if (rc)
- brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
- arg, rc);
- else
- brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
-
-fail:
- kfree(arg_org);
-
- kfree(buf);
-}
-
-static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
-{
- char iovbuf[32];
- int retcode;
-
- brcmu_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
- retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
- iovbuf, sizeof(iovbuf));
- retcode = retcode >= 0 ? 0 : retcode;
- if (retcode)
- brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n",
- arp_mode, retcode);
- else
- brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n",
- arp_mode);
-}
-
-static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
-{
- char iovbuf[32];
- int retcode;
-
- brcmu_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf));
- retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
- iovbuf, sizeof(iovbuf));
- retcode = retcode >= 0 ? 0 : retcode;
- if (retcode)
- brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n",
- arp_enable, retcode);
- else
- brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n",
- arp_enable);
-}
-
-int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
-{
- char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for
- "event_msgs" + '\0' + bitvec */
- uint up = 0;
- char buf[128], *ptr;
- u32 dongle_align = BRCMF_SDALIGN;
- u32 glom = 0;
- u32 roaming = 1;
- uint bcn_timeout = 3;
- int scan_assoc_time = 40;
- int scan_unassoc_time = 40;
- int i;
-
- brcmf_os_proto_block(drvr);
-
- /* Set Country code */
- if (drvr->country_code[0] != 0) {
- if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY,
- drvr->country_code,
- sizeof(drvr->country_code)) < 0)
- brcmf_dbg(ERROR, "country code setting failed\n");
- }
-
- /* query for 'ver' to get version info from firmware */
- memset(buf, 0, sizeof(buf));
- ptr = buf;
- brcmu_mkiovar("ver", NULL, 0, buf, sizeof(buf));
- brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
- strsep(&ptr, "\n");
- /* Print fw version info */
- brcmf_dbg(ERROR, "Firmware version = %s\n", buf);
-
- /* Match Host and Dongle rx alignment */
- brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
- sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
- sizeof(iovbuf));
-
- /* disable glom option per default */
- brcmu_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
- sizeof(iovbuf));
-
- /* Setup timeout if Beacons are lost and roam is off to report
- link down */
- brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
- sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
- sizeof(iovbuf));
-
- /* Enable/Disable build-in roaming to allowed ext supplicant to take
- of romaing */
- brcmu_mkiovar("roam_off", (char *)&roaming, 4,
- iovbuf, sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
- sizeof(iovbuf));
-
- /* Force STA UP */
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
-
- /* Setup event_msgs */
- brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
- iovbuf, sizeof(iovbuf));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
- sizeof(iovbuf));
-
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
- (char *)&scan_assoc_time, sizeof(scan_assoc_time));
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
- (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
-
- /* Set and enable ARP offload feature */
- brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
- brcmf_c_arp_offload_enable(drvr, true);
-
- /* Set up pkt filter */
- for (i = 0; i < drvr->pktfilter_count; i++) {
- brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]);
- brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i],
- 0, true);
- }
-
- brcmf_os_proto_unblock(drvr);
-
- return 0;
-}
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
deleted file mode 100644
index 7467922f0536..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _BRCMF_DBG_H_
-#define _BRCMF_DBG_H_
-
-#if defined(BCMDBG)
-
-#define brcmf_dbg(level, fmt, ...) \
-do { \
- if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) { \
- if (brcmf_msg_level & BRCMF_##level##_VAL) { \
- if (net_ratelimit()) \
- printk(KERN_DEBUG "%s: " fmt, \
- __func__, ##__VA_ARGS__); \
- } \
- } else { \
- if (brcmf_msg_level & BRCMF_##level##_VAL) { \
- printk(KERN_DEBUG "%s: " fmt, \
- __func__, ##__VA_ARGS__); \
- } \
- } \
-} while (0)
-
-#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL)
-#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL)
-#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
-#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL)
-#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
-
-#else /* (defined BCMDBG) || (defined BCMDBG) */
-
-#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
-
-#define BRCMF_DATA_ON() 0
-#define BRCMF_CTL_ON() 0
-#define BRCMF_HDRS_ON() 0
-#define BRCMF_BYTES_ON() 0
-#define BRCMF_GLOM_ON() 0
-
-#endif /* defined(BCMDBG) */
-
-extern int brcmf_msg_level;
-
-#endif /* _BRCMF_DBG_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
deleted file mode 100644
index 99ba5e3e45fa..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/kthread.h>
-#include <linux/slab.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/random.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/fcntl.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-#include <linux/hardirq.h>
-#include <linux/mutex.h>
-#include <linux/wait.h>
-#include <net/cfg80211.h>
-#include <net/rtnetlink.h>
-#include <defs.h>
-#include <brcmu_utils.h>
-#include <brcmu_wifi.h>
-
-#include "dhd.h"
-#include "dhd_bus.h"
-#include "dhd_proto.h"
-#include "dhd_dbg.h"
-#include "wl_cfg80211.h"
-#include "bcmchip.h"
-
-MODULE_AUTHOR("Broadcom Corporation");
-MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
-MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
-MODULE_LICENSE("Dual BSD/GPL");
-
-
-/* Interface control information */
-struct brcmf_if {
- struct brcmf_info *info; /* back pointer to brcmf_info */
- /* OS/stack specifics */
- struct net_device *ndev;
- struct net_device_stats stats;
- int idx; /* iface idx in dongle */
- int state; /* interface state */
- u8 mac_addr[ETH_ALEN]; /* assigned MAC address */
-};
-
-/* Local private structure (extension of pub) */
-struct brcmf_info {
- struct brcmf_pub pub;
-
- /* OS/stack specifics */
- struct brcmf_if *iflist[BRCMF_MAX_IFS];
-
- struct mutex proto_block;
-
- struct work_struct setmacaddr_work;
- struct work_struct multicast_work;
- u8 macvalue[ETH_ALEN];
- atomic_t pend_8021x_cnt;
-};
-
-/* Error bits */
-module_param(brcmf_msg_level, int, 0);
-
-
-static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *ndev)
-{
- int i = 0;
-
- while (i < BRCMF_MAX_IFS) {
- if (drvr_priv->iflist[i] && drvr_priv->iflist[i]->ndev == ndev)
- return i;
- i++;
- }
-
- return BRCMF_BAD_IF;
-}
-
-int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name)
-{
- int i = BRCMF_MAX_IFS;
- struct brcmf_if *ifp;
-
- if (name == NULL || *name == '\0')
- return 0;
-
- while (--i > 0) {
- ifp = drvr_priv->iflist[i];
- if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ))
- break;
- }
-
- brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name);
-
- return i; /* default - the primary interface */
-}
-
-char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
-{
- struct brcmf_info *drvr_priv = drvr->info;
-
- if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
- brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx);
- return "<if_bad>";
- }
-
- if (drvr_priv->iflist[ifidx] == NULL) {
- brcmf_dbg(ERROR, "null i/f %d\n", ifidx);
- return "<if_null>";
- }
-
- if (drvr_priv->iflist[ifidx]->ndev)
- return drvr_priv->iflist[ifidx]->ndev->name;
-
- return "<if_none>";
-}
-
-static void _brcmf_set_multicast_list(struct work_struct *work)
-{
- struct net_device *ndev;
- struct netdev_hw_addr *ha;
- u32 allmulti, cnt;
- __le32 cnt_le;
- __le32 allmulti_le;
-
- struct brcmf_dcmd dcmd;
- char *buf, *bufp;
- uint buflen;
- int ret;
-
- struct brcmf_info *drvr_priv = container_of(work, struct brcmf_info,
- multicast_work);
-
- ndev = drvr_priv->iflist[0]->ndev;
- cnt = netdev_mc_count(ndev);
-
- /* Determine initial value of allmulti flag */
- allmulti = (ndev->flags & IFF_ALLMULTI) ? true : false;
-
- /* Send down the multicast list first. */
-
- buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
- bufp = buf = kmalloc(buflen, GFP_ATOMIC);
- if (!bufp)
- return;
-
- strcpy(bufp, "mcast_list");
- bufp += strlen("mcast_list") + 1;
-
- cnt_le = cpu_to_le32(cnt);
- memcpy(bufp, &cnt_le, sizeof(cnt));
- bufp += sizeof(cnt_le);
-
- netdev_for_each_mc_addr(ha, ndev) {
- if (!cnt)
- break;
- memcpy(bufp, ha->addr, ETH_ALEN);
- bufp += ETH_ALEN;
- cnt--;
- }
-
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = BRCMF_C_SET_VAR;
- dcmd.buf = buf;
- dcmd.len = buflen;
- dcmd.set = true;
-
- ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
- brcmf_ifname(&drvr_priv->pub, 0), cnt);
- allmulti = cnt ? true : allmulti;
- }
-
- kfree(buf);
-
- /* Now send the allmulti setting. This is based on the setting in the
- * net_device flags, but might be modified above to be turned on if we
- * were trying to set some addresses and dongle rejected it...
- */
-
- buflen = sizeof("allmulti") + sizeof(allmulti);
- buf = kmalloc(buflen, GFP_ATOMIC);
- if (!buf)
- return;
-
- allmulti_le = cpu_to_le32(allmulti);
-
- if (!brcmu_mkiovar
- ("allmulti", (void *)&allmulti_le,
- sizeof(allmulti_le), buf, buflen)) {
- brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
- brcmf_ifname(&drvr_priv->pub, 0),
- (int)sizeof(allmulti), buflen);
- kfree(buf);
- return;
- }
-
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = BRCMF_C_SET_VAR;
- dcmd.buf = buf;
- dcmd.len = buflen;
- dcmd.set = true;
-
- ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
- brcmf_ifname(&drvr_priv->pub, 0),
- le32_to_cpu(allmulti_le));
- }
-
- kfree(buf);
-
- /* Finally, pick up the PROMISC flag as well, like the NIC
- driver does */
-
- allmulti = (ndev->flags & IFF_PROMISC) ? true : false;
- allmulti_le = cpu_to_le32(allmulti);
-
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = BRCMF_C_SET_PROMISC;
- dcmd.buf = &allmulti_le;
- dcmd.len = sizeof(allmulti_le);
- dcmd.set = true;
-
- ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
- brcmf_ifname(&drvr_priv->pub, 0),
- le32_to_cpu(allmulti_le));
- }
-}
-
-static void
-_brcmf_set_mac_address(struct work_struct *work)
-{
- char buf[32];
- struct brcmf_dcmd dcmd;
- int ret;
-
- struct brcmf_info *drvr_priv = container_of(work, struct brcmf_info,
- setmacaddr_work);
-
- brcmf_dbg(TRACE, "enter\n");
- if (!brcmu_mkiovar("cur_etheraddr", (char *)drvr_priv->macvalue,
- ETH_ALEN, buf, 32)) {
- brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
- brcmf_ifname(&drvr_priv->pub, 0));
- return;
- }
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = BRCMF_C_SET_VAR;
- dcmd.buf = buf;
- dcmd.len = 32;
- dcmd.set = true;
-
- ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len);
- if (ret < 0)
- brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n",
- brcmf_ifname(&drvr_priv->pub, 0));
- else
- memcpy(drvr_priv->iflist[0]->ndev->dev_addr,
- drvr_priv->macvalue, ETH_ALEN);
-
- return;
-}
-
-static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
-{
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)
- netdev_priv(ndev);
- struct sockaddr *sa = (struct sockaddr *)addr;
- int ifidx;
-
- ifidx = brcmf_net2idx(drvr_priv, ndev);
- if (ifidx == BRCMF_BAD_IF)
- return -1;
-
- memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN);
- schedule_work(&drvr_priv->setmacaddr_work);
- return 0;
-}
-
-static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
-{
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)
- netdev_priv(ndev);
- int ifidx;
-
- ifidx = brcmf_net2idx(drvr_priv, ndev);
- if (ifidx == BRCMF_BAD_IF)
- return;
-
- schedule_work(&drvr_priv->multicast_work);
-}
-
-int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
-{
- struct brcmf_info *drvr_priv = drvr->info;
-
- /* Reject if down */
- if (!drvr->up || (drvr->busstate == BRCMF_BUS_DOWN))
- return -ENODEV;
-
- /* Update multicast statistic */
- if (pktbuf->len >= ETH_ALEN) {
- u8 *pktdata = (u8 *) (pktbuf->data);
- struct ethhdr *eh = (struct ethhdr *)pktdata;
-
- if (is_multicast_ether_addr(eh->h_dest))
- drvr->tx_multicast++;
- if (ntohs(eh->h_proto) == ETH_P_PAE)
- atomic_inc(&drvr_priv->pend_8021x_cnt);
- }
-
- /* If the protocol uses a data header, apply it */
- brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
-
- /* Use bus module to send data frame */
- return brcmf_sdbrcm_bus_txdata(drvr->bus, pktbuf);
-}
-
-static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
- int ret;
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)
- netdev_priv(ndev);
- int ifidx;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Reject if down */
- if (!drvr_priv->pub.up || (drvr_priv->pub.busstate == BRCMF_BUS_DOWN)) {
- brcmf_dbg(ERROR, "xmit rejected pub.up=%d busstate=%d\n",
- drvr_priv->pub.up, drvr_priv->pub.busstate);
- netif_stop_queue(ndev);
- return -ENODEV;
- }
-
- ifidx = brcmf_net2idx(drvr_priv, ndev);
- if (ifidx == BRCMF_BAD_IF) {
- brcmf_dbg(ERROR, "bad ifidx %d\n", ifidx);
- netif_stop_queue(ndev);
- return -ENODEV;
- }
-
- /* Make sure there's enough room for any header */
- if (skb_headroom(skb) < drvr_priv->pub.hdrlen) {
- struct sk_buff *skb2;
-
- brcmf_dbg(INFO, "%s: insufficient headroom\n",
- brcmf_ifname(&drvr_priv->pub, ifidx));
- drvr_priv->pub.tx_realloc++;
- skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen);
- dev_kfree_skb(skb);
- skb = skb2;
- if (skb == NULL) {
- brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n",
- brcmf_ifname(&drvr_priv->pub, ifidx));
- ret = -ENOMEM;
- goto done;
- }
- }
-
- ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb);
-
-done:
- if (ret)
- drvr_priv->pub.dstats.tx_dropped++;
- else
- drvr_priv->pub.tx_packets++;
-
- /* Return ok: we always eat the packet */
- return 0;
-}
-
-void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state)
-{
- struct net_device *ndev;
- struct brcmf_info *drvr_priv = drvr->info;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- drvr->txoff = state;
- ndev = drvr_priv->iflist[ifidx]->ndev;
- if (state == ON)
- netif_stop_queue(ndev);
- else
- netif_wake_queue(ndev);
-}
-
-static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx,
- void *pktdata, struct brcmf_event_msg *event,
- void **data)
-{
- int bcmerror = 0;
-
- bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data);
- if (bcmerror != 0)
- return bcmerror;
-
- if (drvr_priv->iflist[*ifidx]->ndev)
- brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->ndev,
- event, *data);
-
- return bcmerror;
-}
-
-void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb,
- int numpkt)
-{
- struct brcmf_info *drvr_priv = drvr->info;
- unsigned char *eth;
- uint len;
- void *data;
- struct sk_buff *pnext, *save_pktbuf;
- int i;
- struct brcmf_if *ifp;
- struct brcmf_event_msg event;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- save_pktbuf = skb;
-
- for (i = 0; skb && i < numpkt; i++, skb = pnext) {
-
- pnext = skb->next;
- skb->next = NULL;
-
- /* Get the protocol, maintain skb around eth_type_trans()
- * The main reason for this hack is for the limitation of
- * Linux 2.4 where 'eth_type_trans' uses the
- * 'net->hard_header_len'
- * to perform skb_pull inside vs ETH_HLEN. Since to avoid
- * coping of the packet coming from the network stack to add
- * BDC, Hardware header etc, during network interface
- * registration
- * we set the 'net->hard_header_len' to ETH_HLEN + extra space
- * required
- * for BDC, Hardware header etc. and not just the ETH_HLEN
- */
- eth = skb->data;
- len = skb->len;
-
- ifp = drvr_priv->iflist[ifidx];
- if (ifp == NULL)
- ifp = drvr_priv->iflist[0];
-
- skb->dev = ifp->ndev;
- skb->protocol = eth_type_trans(skb, skb->dev);
-
- if (skb->pkt_type == PACKET_MULTICAST)
- drvr_priv->pub.rx_multicast++;
-
- skb->data = eth;
- skb->len = len;
-
- /* Strip header, count, deliver upward */
- skb_pull(skb, ETH_HLEN);
-
- /* Process special event packets and then discard them */
- if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
- brcmf_host_event(drvr_priv, &ifidx,
- skb_mac_header(skb),
- &event, &data);
-
- if (drvr_priv->iflist[ifidx] &&
- !drvr_priv->iflist[ifidx]->state)
- ifp = drvr_priv->iflist[ifidx];
-
- if (ifp->ndev)
- ifp->ndev->last_rx = jiffies;
-
- drvr->dstats.rx_bytes += skb->len;
- drvr->rx_packets++; /* Local count */
-
- if (in_interrupt())
- netif_rx(skb);
- else
- /* If the receive is not processed inside an ISR,
- * the softirqd must be woken explicitly to service
- * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled
- * by netif_rx_ni(), but in earlier kernels, we need
- * to do it manually.
- */
- netif_rx_ni(skb);
- }
-}
-
-void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success)
-{
- uint ifidx;
- struct brcmf_info *drvr_priv = drvr->info;
- struct ethhdr *eh;
- u16 type;
-
- brcmf_proto_hdrpull(drvr, &ifidx, txp);
-
- eh = (struct ethhdr *)(txp->data);
- type = ntohs(eh->h_proto);
-
- if (type == ETH_P_PAE)
- atomic_dec(&drvr_priv->pend_8021x_cnt);
-
-}
-
-static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
-{
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)
- netdev_priv(ndev);
- struct brcmf_if *ifp;
- int ifidx;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- ifidx = brcmf_net2idx(drvr_priv, ndev);
- if (ifidx == BRCMF_BAD_IF)
- return NULL;
-
- ifp = drvr_priv->iflist[ifidx];
-
- if (drvr_priv->pub.up)
- /* Use the protocol to get dongle stats */
- brcmf_proto_dstats(&drvr_priv->pub);
-
- /* Copy dongle stats to net device stats */
- ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets;
- ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets;
- ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes;
- ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes;
- ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors;
- ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors;
- ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped;
- ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped;
- ifp->stats.multicast = drvr_priv->pub.dstats.multicast;
-
- return &ifp->stats;
-}
-
-/* Retrieve current toe component enables, which are kept
- as a bitmap in toe_ol iovar */
-static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
-{
- struct brcmf_dcmd dcmd;
- char buf[32];
- int ret;
-
- memset(&dcmd, 0, sizeof(dcmd));
-
- dcmd.cmd = BRCMF_C_GET_VAR;
- dcmd.buf = buf;
- dcmd.len = (uint) sizeof(buf);
- dcmd.set = false;
-
- strcpy(buf, "toe_ol");
- ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len);
- if (ret < 0) {
- /* Check for older dongle image that doesn't support toe_ol */
- if (ret == -EIO) {
- brcmf_dbg(ERROR, "%s: toe not supported by device\n",
- brcmf_ifname(&drvr_priv->pub, ifidx));
- return -EOPNOTSUPP;
- }
-
- brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
- brcmf_ifname(&drvr_priv->pub, ifidx), ret);
- return ret;
- }
-
- memcpy(toe_ol, buf, sizeof(u32));
- return 0;
-}
-
-/* Set current toe component enables in toe_ol iovar,
- and set toe global enable iovar */
-static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
-{
- struct brcmf_dcmd dcmd;
- char buf[32];
- int toe, ret;
-
- memset(&dcmd, 0, sizeof(dcmd));
-
- dcmd.cmd = BRCMF_C_SET_VAR;
- dcmd.buf = buf;
- dcmd.len = (uint) sizeof(buf);
- dcmd.set = true;
-
- /* Set toe_ol as requested */
-
- strcpy(buf, "toe_ol");
- memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32));
-
- ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
- brcmf_ifname(&drvr_priv->pub, ifidx), ret);
- return ret;
- }
-
- /* Enable toe globally only if any components are enabled. */
-
- toe = (toe_ol != 0);
-
- strcpy(buf, "toe");
- memcpy(&buf[sizeof("toe")], &toe, sizeof(u32));
-
- ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
- brcmf_ifname(&drvr_priv->pub, ifidx), ret);
- return ret;
- }
-
- return 0;
-}
-
-static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
- struct ethtool_drvinfo *info)
-{
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)
- netdev_priv(ndev);
-
- sprintf(info->driver, KBUILD_MODNAME);
- sprintf(info->version, "%lu", drvr_priv->pub.drv_version);
- sprintf(info->fw_version, "%s", BCM4329_FW_NAME);
- sprintf(info->bus_info, "%s",
- dev_name(brcmf_bus_get_device(drvr_priv->pub.bus)));
-}
-
-static struct ethtool_ops brcmf_ethtool_ops = {
- .get_drvinfo = brcmf_ethtool_get_drvinfo
-};
-
-static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr)
-{
- struct ethtool_drvinfo info;
- char drvname[sizeof(info.driver)];
- u32 cmd;
- struct ethtool_value edata;
- u32 toe_cmpnt, csum_dir;
- int ret;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* all ethtool calls start with a cmd word */
- if (copy_from_user(&cmd, uaddr, sizeof(u32)))
- return -EFAULT;
-
- switch (cmd) {
- case ETHTOOL_GDRVINFO:
- /* Copy out any request driver name */
- if (copy_from_user(&info, uaddr, sizeof(info)))
- return -EFAULT;
- strncpy(drvname, info.driver, sizeof(info.driver));
- drvname[sizeof(info.driver) - 1] = '\0';
-
- /* clear struct for return */
- memset(&info, 0, sizeof(info));
- info.cmd = cmd;
-
- /* if requested, identify ourselves */
- if (strcmp(drvname, "?dhd") == 0) {
- sprintf(info.driver, "dhd");
- strcpy(info.version, BRCMF_VERSION_STR);
- }
-
- /* otherwise, require dongle to be up */
- else if (!drvr_priv->pub.up) {
- brcmf_dbg(ERROR, "dongle is not up\n");
- return -ENODEV;
- }
-
- /* finally, report dongle driver type */
- else if (drvr_priv->pub.iswl)
- sprintf(info.driver, "wl");
- else
- sprintf(info.driver, "xx");
-
- sprintf(info.version, "%lu", drvr_priv->pub.drv_version);
- if (copy_to_user(uaddr, &info, sizeof(info)))
- return -EFAULT;
- brcmf_dbg(CTL, "given %*s, returning %s\n",
- (int)sizeof(drvname), drvname, info.driver);
- break;
-
- /* Get toe offload components from dongle */
- case ETHTOOL_GRXCSUM:
- case ETHTOOL_GTXCSUM:
- ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
- if (ret < 0)
- return ret;
-
- csum_dir =
- (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
-
- edata.cmd = cmd;
- edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
-
- if (copy_to_user(uaddr, &edata, sizeof(edata)))
- return -EFAULT;
- break;
-
- /* Set toe offload components in dongle */
- case ETHTOOL_SRXCSUM:
- case ETHTOOL_STXCSUM:
- if (copy_from_user(&edata, uaddr, sizeof(edata)))
- return -EFAULT;
-
- /* Read the current settings, update and write back */
- ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
- if (ret < 0)
- return ret;
-
- csum_dir =
- (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
-
- if (edata.data != 0)
- toe_cmpnt |= csum_dir;
- else
- toe_cmpnt &= ~csum_dir;
-
- ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt);
- if (ret < 0)
- return ret;
-
- /* If setting TX checksum mode, tell Linux the new mode */
- if (cmd == ETHTOOL_STXCSUM) {
- if (edata.data)
- drvr_priv->iflist[0]->ndev->features |=
- NETIF_F_IP_CSUM;
- else
- drvr_priv->iflist[0]->ndev->features &=
- ~NETIF_F_IP_CSUM;
- }
-
- break;
-
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
- int cmd)
-{
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)
- netdev_priv(ndev);
- int ifidx;
-
- ifidx = brcmf_net2idx(drvr_priv, ndev);
- brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifidx, cmd);
-
- if (ifidx == BRCMF_BAD_IF)
- return -1;
-
- if (cmd == SIOCETHTOOL)
- return brcmf_ethtool(drvr_priv, ifr->ifr_data);
-
- return -EOPNOTSUPP;
-}
-
-/* called only from within this driver. Sends a command to the dongle. */
-s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
-{
- struct brcmf_dcmd dcmd;
- s32 err = 0;
- int buflen = 0;
- bool is_set_key_cmd;
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)
- netdev_priv(ndev);
- int ifidx;
-
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = cmd;
- dcmd.buf = arg;
- dcmd.len = len;
-
- ifidx = brcmf_net2idx(drvr_priv, ndev);
-
- if (dcmd.buf != NULL)
- buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN);
-
- /* send to dongle (must be up, and wl) */
- if ((drvr_priv->pub.busstate != BRCMF_BUS_DATA)) {
- brcmf_dbg(ERROR, "DONGLE_DOWN\n");
- err = -EIO;
- goto done;
- }
-
- if (!drvr_priv->pub.iswl) {
- err = -EIO;
- goto done;
- }
-
- /*
- * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and
- * set key CMD to prevent M4 encryption.
- */
- is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) ||
- ((dcmd.cmd == BRCMF_C_SET_VAR) &&
- !(strncmp("wsec_key", dcmd.buf, 9))) ||
- ((dcmd.cmd == BRCMF_C_SET_VAR) &&
- !(strncmp("bsscfg:wsec_key", dcmd.buf, 15))));
- if (is_set_key_cmd)
- brcmf_netdev_wait_pend8021x(ndev);
-
- err = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, buflen);
-
-done:
- if (err > 0)
- err = 0;
-
- return err;
-}
-
-static int brcmf_netdev_stop(struct net_device *ndev)
-{
- struct brcmf_pub *drvr = *(struct brcmf_pub **) netdev_priv(ndev);
-
- brcmf_dbg(TRACE, "Enter\n");
- brcmf_cfg80211_down(drvr->config);
- if (drvr->up == 0)
- return 0;
-
- /* Set state and stop OS transmissions */
- drvr->up = 0;
- netif_stop_queue(ndev);
-
- return 0;
-}
-
-static int brcmf_netdev_open(struct net_device *ndev)
-{
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)
- netdev_priv(ndev);
- u32 toe_ol;
- int ifidx = brcmf_net2idx(drvr_priv, ndev);
- s32 ret = 0;
-
- brcmf_dbg(TRACE, "ifidx %d\n", ifidx);
-
- if (ifidx == 0) { /* do it only for primary eth0 */
-
- /* try to bring up bus */
- ret = brcmf_bus_start(&drvr_priv->pub);
- if (ret != 0) {
- brcmf_dbg(ERROR, "failed with code %d\n", ret);
- return -1;
- }
- atomic_set(&drvr_priv->pend_8021x_cnt, 0);
-
- memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN);
-
- /* Get current TOE mode from dongle */
- if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0
- && (toe_ol & TOE_TX_CSUM_OL) != 0)
- drvr_priv->iflist[ifidx]->ndev->features |=
- NETIF_F_IP_CSUM;
- else
- drvr_priv->iflist[ifidx]->ndev->features &=
- ~NETIF_F_IP_CSUM;
- }
- /* Allow transmit calls */
- netif_start_queue(ndev);
- drvr_priv->pub.up = 1;
- if (brcmf_cfg80211_up(drvr_priv->pub.config)) {
- brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
- return -1;
- }
-
- return ret;
-}
-
-int
-brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *ndev,
- char *name, u8 *mac_addr, u32 flags, u8 bssidx)
-{
- struct brcmf_if *ifp;
- int ret = 0, err = 0;
-
- brcmf_dbg(TRACE, "idx %d, handle->%p\n", ifidx, ndev);
-
- ifp = drvr_priv->iflist[ifidx];
- if (!ifp) {
- ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC);
- if (!ifp)
- return -ENOMEM;
- }
-
- memset(ifp, 0, sizeof(struct brcmf_if));
- ifp->info = drvr_priv;
- drvr_priv->iflist[ifidx] = ifp;
- if (mac_addr != NULL)
- memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
-
- if (ndev == NULL) {
- ifp->state = BRCMF_E_IF_ADD;
- ifp->idx = ifidx;
- /*
- * Delete the existing interface before overwriting it
- * in case we missed the BRCMF_E_IF_DEL event.
- */
- if (ifp->ndev != NULL) {
- brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n",
- ifp->ndev->name);
- netif_stop_queue(ifp->ndev);
- unregister_netdev(ifp->ndev);
- free_netdev(ifp->ndev);
- }
-
- /* Allocate netdev, including space for private structure */
- ifp->ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d",
- ether_setup);
- if (!ifp->ndev) {
- brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
- ret = -ENOMEM;
- }
-
- if (ret == 0) {
- memcpy(netdev_priv(ifp->ndev), &drvr_priv,
- sizeof(drvr_priv));
- err = brcmf_net_attach(&drvr_priv->pub, ifp->idx);
- if (err != 0) {
- brcmf_dbg(ERROR, "brcmf_net_attach failed, err %d\n",
- err);
- ret = -EOPNOTSUPP;
- } else {
- brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
- current->pid, ifp->ndev->name);
- ifp->state = 0;
- }
- }
-
- if (ret < 0) {
- if (ifp->ndev)
- free_netdev(ifp->ndev);
-
- drvr_priv->iflist[ifp->idx] = NULL;
- kfree(ifp);
- }
- } else
- ifp->ndev = ndev;
-
- return 0;
-}
-
-void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx)
-{
- struct brcmf_if *ifp;
-
- brcmf_dbg(TRACE, "idx %d\n", ifidx);
-
- ifp = drvr_priv->iflist[ifidx];
- if (!ifp) {
- brcmf_dbg(ERROR, "Null interface\n");
- return;
- }
-
- ifp->state = BRCMF_E_IF_DEL;
- ifp->idx = ifidx;
- if (ifp->ndev != NULL) {
- netif_stop_queue(ifp->ndev);
- unregister_netdev(ifp->ndev);
- free_netdev(ifp->ndev);
- drvr_priv->iflist[ifidx] = NULL;
- kfree(ifp);
- }
-}
-
-struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen)
-{
- struct brcmf_info *drvr_priv = NULL;
- struct net_device *ndev;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Allocate netdev, including space for private structure */
- ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", ether_setup);
- if (!ndev) {
- brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
- goto fail;
- }
-
- /* Allocate primary brcmf_info */
- drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC);
- if (!drvr_priv)
- goto fail;
-
- /*
- * Save the brcmf_info into the priv
- */
- memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv));
-
- if (brcmf_add_if(drvr_priv, 0, ndev, ndev->name, NULL, 0, 0) ==
- BRCMF_BAD_IF)
- goto fail;
-
- ndev->netdev_ops = NULL;
- mutex_init(&drvr_priv->proto_block);
-
- /* Link to info module */
- drvr_priv->pub.info = drvr_priv;
-
- /* Link to bus module */
- drvr_priv->pub.bus = bus;
- drvr_priv->pub.hdrlen = bus_hdrlen;
-
- /* Attach and link in the protocol */
- if (brcmf_proto_attach(&drvr_priv->pub) != 0) {
- brcmf_dbg(ERROR, "brcmf_prot_attach failed\n");
- goto fail;
- }
-
- /* Attach and link in the cfg80211 */
- drvr_priv->pub.config =
- brcmf_cfg80211_attach(ndev,
- brcmf_bus_get_device(bus),
- &drvr_priv->pub);
- if (drvr_priv->pub.config == NULL) {
- brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
- goto fail;
- }
-
- INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address);
- INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list);
-
- /*
- * Save the brcmf_info into the priv
- */
- memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv));
-
- return &drvr_priv->pub;
-
-fail:
- if (ndev)
- free_netdev(ndev);
- if (drvr_priv)
- brcmf_detach(&drvr_priv->pub);
-
- return NULL;
-}
-
-int brcmf_bus_start(struct brcmf_pub *drvr)
-{
- int ret = -1;
- struct brcmf_info *drvr_priv = drvr->info;
- /* Room for "event_msgs" + '\0' + bitvec */
- char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
-
- brcmf_dbg(TRACE, "\n");
-
- /* Bring up the bus */
- ret = brcmf_sdbrcm_bus_init(&drvr_priv->pub);
- if (ret != 0) {
- brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
- return ret;
- }
-
- /* If bus is not ready, can't come up */
- if (drvr_priv->pub.busstate != BRCMF_BUS_DATA) {
- brcmf_dbg(ERROR, "failed bus is not ready\n");
- return -ENODEV;
- }
-
- brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
- iovbuf, sizeof(iovbuf));
- brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
- sizeof(iovbuf));
- memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
-
- setbit(drvr->eventmask, BRCMF_E_SET_SSID);
- setbit(drvr->eventmask, BRCMF_E_PRUNE);
- setbit(drvr->eventmask, BRCMF_E_AUTH);
- setbit(drvr->eventmask, BRCMF_E_REASSOC);
- setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
- setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
- setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
- setbit(drvr->eventmask, BRCMF_E_DISASSOC);
- setbit(drvr->eventmask, BRCMF_E_JOIN);
- setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
- setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
- setbit(drvr->eventmask, BRCMF_E_LINK);
- setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
- setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
- setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
- setbit(drvr->eventmask, BRCMF_E_TXFAIL);
- setbit(drvr->eventmask, BRCMF_E_JOIN_START);
- setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
-
-/* enable dongle roaming event */
-
- drvr->pktfilter_count = 1;
- /* Setup filter to allow only unicast */
- drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
-
- /* Bus is ready, do any protocol initialization */
- ret = brcmf_proto_init(&drvr_priv->pub);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static struct net_device_ops brcmf_netdev_ops_pri = {
- .ndo_open = brcmf_netdev_open,
- .ndo_stop = brcmf_netdev_stop,
- .ndo_get_stats = brcmf_netdev_get_stats,
- .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
- .ndo_start_xmit = brcmf_netdev_start_xmit,
- .ndo_set_mac_address = brcmf_netdev_set_mac_address,
- .ndo_set_multicast_list = brcmf_netdev_set_multicast_list
-};
-
-int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
-{
- struct brcmf_info *drvr_priv = drvr->info;
- struct net_device *ndev;
- u8 temp_addr[ETH_ALEN] = {
- 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
-
- brcmf_dbg(TRACE, "ifidx %d\n", ifidx);
-
- ndev = drvr_priv->iflist[ifidx]->ndev;
- ndev->netdev_ops = &brcmf_netdev_ops_pri;
-
- /*
- * We have to use the primary MAC for virtual interfaces
- */
- if (ifidx != 0) {
- /* for virtual interfaces use the primary MAC */
- memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN);
-
- }
-
- if (ifidx == 1) {
- brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
- /* ACCESSPOINT INTERFACE CASE */
- temp_addr[0] |= 0X02; /* set bit 2 ,
- - Locally Administered address */
-
- }
- ndev->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen;
- ndev->ethtool_ops = &brcmf_ethtool_ops;
-
- drvr_priv->pub.rxsz = ndev->mtu + ndev->hard_header_len +
- drvr_priv->pub.hdrlen;
-
- memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
-
- if (register_netdev(ndev) != 0) {
- brcmf_dbg(ERROR, "couldn't register the net device\n");
- goto fail;
- }
-
- brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
-
- return 0;
-
-fail:
- ndev->netdev_ops = NULL;
- return -EBADE;
-}
-
-static void brcmf_bus_detach(struct brcmf_pub *drvr)
-{
- struct brcmf_info *drvr_priv;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (drvr) {
- drvr_priv = drvr->info;
- if (drvr_priv) {
- /* Stop the protocol module */
- brcmf_proto_stop(&drvr_priv->pub);
-
- /* Stop the bus module */
- brcmf_sdbrcm_bus_stop(drvr_priv->pub.bus);
- }
- }
-}
-
-void brcmf_detach(struct brcmf_pub *drvr)
-{
- struct brcmf_info *drvr_priv;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (drvr) {
- drvr_priv = drvr->info;
- if (drvr_priv) {
- struct brcmf_if *ifp;
- int i;
-
- for (i = 1; i < BRCMF_MAX_IFS; i++)
- if (drvr_priv->iflist[i])
- brcmf_del_if(drvr_priv, i);
-
- ifp = drvr_priv->iflist[0];
- if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
- rtnl_lock();
- brcmf_netdev_stop(ifp->ndev);
- rtnl_unlock();
- unregister_netdev(ifp->ndev);
- }
-
- cancel_work_sync(&drvr_priv->setmacaddr_work);
- cancel_work_sync(&drvr_priv->multicast_work);
-
- brcmf_bus_detach(drvr);
-
- if (drvr->prot)
- brcmf_proto_detach(drvr);
-
- brcmf_cfg80211_detach(drvr->config);
-
- free_netdev(ifp->ndev);
- kfree(ifp);
- kfree(drvr_priv);
- }
- }
-}
-
-static void __exit brcmf_module_cleanup(void)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- brcmf_bus_unregister();
-}
-
-static int __init brcmf_module_init(void)
-{
- int error;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- error = brcmf_bus_register();
-
- if (error) {
- brcmf_dbg(ERROR, "brcmf_bus_register failed\n");
- goto failed;
- }
- return 0;
-
-failed:
- return -EINVAL;
-}
-
-module_init(brcmf_module_init);
-module_exit(brcmf_module_cleanup);
-
-int brcmf_os_proto_block(struct brcmf_pub *drvr)
-{
- struct brcmf_info *drvr_priv = drvr->info;
-
- if (drvr_priv) {
- mutex_lock(&drvr_priv->proto_block);
- return 1;
- }
- return 0;
-}
-
-int brcmf_os_proto_unblock(struct brcmf_pub *drvr)
-{
- struct brcmf_info *drvr_priv = drvr->info;
-
- if (drvr_priv) {
- mutex_unlock(&drvr_priv->proto_block);
- return 1;
- }
-
- return 0;
-}
-
-static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv)
-{
- return atomic_read(&drvr_priv->pend_8021x_cnt);
-}
-
-#define MAX_WAIT_FOR_8021X_TX 10
-
-int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
-{
- struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(ndev);
- int timeout = 10 * HZ / 1000;
- int ntimes = MAX_WAIT_FOR_8021X_TX;
- int pend = brcmf_get_pend_8021x_cnt(drvr_priv);
-
- while (ntimes && pend) {
- if (pend) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(timeout);
- set_current_state(TASK_RUNNING);
- ntimes--;
- }
- pend = brcmf_get_pend_8021x_cnt(drvr_priv);
- }
- return pend;
-}
-
-#ifdef BCMDBG
-int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size)
-{
- int ret = 0;
- struct file *fp;
- mm_segment_t old_fs;
- loff_t pos = 0;
-
- /* change to KERNEL_DS address limit */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- /* open file to write */
- fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
- if (!fp) {
- brcmf_dbg(ERROR, "open file error\n");
- ret = -1;
- goto exit;
- }
-
- /* Write buf to file */
- fp->f_op->write(fp, buf, size, &pos);
-
-exit:
- /* free buf before return */
- kfree(buf);
- /* close file before return */
- if (fp)
- filp_close(fp, current->files);
- /* restore previous address limit */
- set_fs(old_fs);
-
- return ret;
-}
-#endif /* BCMDBG */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h
deleted file mode 100644
index 4ee1ea846f6d..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _BRCMF_PROTO_H_
-#define _BRCMF_PROTO_H_
-
-/*
- * Exported from the brcmf protocol module (brcmf_cdc)
- */
-
-/* Linkage, sets prot link and updates hdrlen in pub */
-extern int brcmf_proto_attach(struct brcmf_pub *drvr);
-
-/* Unlink, frees allocated protocol memory (including brcmf_proto) */
-extern void brcmf_proto_detach(struct brcmf_pub *drvr);
-
-/* Initialize protocol: sync w/dongle state.
- * Sets dongle media info (iswl, drv_version, mac address).
- */
-extern int brcmf_proto_init(struct brcmf_pub *drvr);
-
-/* Stop protocol: sync w/dongle state. */
-extern void brcmf_proto_stop(struct brcmf_pub *drvr);
-
-/* Add any protocol-specific data header.
- * Caller must reserve prot_hdrlen prepend space.
- */
-extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
- struct sk_buff *txp);
-
-/* Remove any protocol-specific data header. */
-extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx,
- struct sk_buff *rxp);
-
-/* Use protocol to issue command to dongle */
-extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
- struct brcmf_dcmd *dcmd, int len);
-
-/* Update local copy of dongle statistics */
-extern void brcmf_proto_dstats(struct brcmf_pub *drvr);
-
-extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr);
-
-extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
- uint cmd, void *buf, uint len);
-
-#endif /* _BRCMF_PROTO_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
deleted file mode 100644
index 6885755f4ec6..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
+++ /dev/null
@@ -1,4581 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/kthread.h>
-#include <linux/printk.h>
-#include <linux/pci_ids.h>
-#include <linux/netdevice.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/card.h>
-#include <linux/semaphore.h>
-#include <linux/firmware.h>
-#include <asm/unaligned.h>
-#include <defs.h>
-#include <brcmu_wifi.h>
-#include <brcmu_utils.h>
-#include <brcm_hw_ids.h>
-#include <soc.h>
-#include "sdio_host.h"
-
-#define DCMD_RESP_TIMEOUT 2000 /* In milli second */
-
-#ifdef BCMDBG
-
-#define BRCMF_TRAP_INFO_SIZE 80
-
-#define CBUF_LEN (128)
-
-struct rte_log_le {
- __le32 buf; /* Can't be pointer on (64-bit) hosts */
- __le32 buf_size;
- __le32 idx;
- char *_buf_compat; /* Redundant pointer for backward compat. */
-};
-
-struct rte_console {
- /* Virtual UART
- * When there is no UART (e.g. Quickturn),
- * the host should write a complete
- * input line directly into cbuf and then write
- * the length into vcons_in.
- * This may also be used when there is a real UART
- * (at risk of conflicting with
- * the real UART). vcons_out is currently unused.
- */
- uint vcons_in;
- uint vcons_out;
-
- /* Output (logging) buffer
- * Console output is written to a ring buffer log_buf at index log_idx.
- * The host may read the output when it sees log_idx advance.
- * Output will be lost if the output wraps around faster than the host
- * polls.
- */
- struct rte_log_le log_le;
-
- /* Console input line buffer
- * Characters are read one at a time into cbuf
- * until <CR> is received, then
- * the buffer is processed as a command line.
- * Also used for virtual UART.
- */
- uint cbuf_idx;
- char cbuf[CBUF_LEN];
-};
-
-#endif /* BCMDBG */
-#include <chipcommon.h>
-
-#include "dhd.h"
-#include "dhd_bus.h"
-#include "dhd_proto.h"
-#include "dhd_dbg.h"
-#include <bcmchip.h>
-
-#define TXQLEN 2048 /* bulk tx queue length */
-#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */
-#define TXLOW (TXHI - 256) /* turn off flow control below TXLOW */
-#define PRIOMASK 7
-
-#define TXRETRIES 2 /* # of retries for tx frames */
-
-#define BRCMF_RXBOUND 50 /* Default for max rx frames in
- one scheduling */
-
-#define BRCMF_TXBOUND 20 /* Default for max tx frames in
- one scheduling */
-
-#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
-
-#define MEMBLOCK 2048 /* Block size used for downloading
- of dongle image */
-#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold
- biggest possible glom */
-
-#define BRCMF_FIRSTREAD (1 << 6)
-
-
-/* SBSDIO_DEVICE_CTL */
-
-/* 1: device will assert busy signal when receiving CMD53 */
-#define SBSDIO_DEVCTL_SETBUSY 0x01
-/* 1: assertion of sdio interrupt is synchronous to the sdio clock */
-#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02
-/* 1: mask all interrupts to host except the chipActive (rev 8) */
-#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04
-/* 1: isolate internal sdio signals, put external pads in tri-state; requires
- * sdio bus power cycle to clear (rev 9) */
-#define SBSDIO_DEVCTL_PADS_ISO 0x08
-/* Force SD->SB reset mapping (rev 11) */
-#define SBSDIO_DEVCTL_SB_RST_CTL 0x30
-/* Determined by CoreControl bit */
-#define SBSDIO_DEVCTL_RST_CORECTL 0x00
-/* Force backplane reset */
-#define SBSDIO_DEVCTL_RST_BPRESET 0x10
-/* Force no backplane reset */
-#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20
-
-/* SBSDIO_FUNC1_CHIPCLKCSR */
-
-/* Force ALP request to backplane */
-#define SBSDIO_FORCE_ALP 0x01
-/* Force HT request to backplane */
-#define SBSDIO_FORCE_HT 0x02
-/* Force ILP request to backplane */
-#define SBSDIO_FORCE_ILP 0x04
-/* Make ALP ready (power up xtal) */
-#define SBSDIO_ALP_AVAIL_REQ 0x08
-/* Make HT ready (power up PLL) */
-#define SBSDIO_HT_AVAIL_REQ 0x10
-/* Squelch clock requests from HW */
-#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
-/* Status: ALP is ready */
-#define SBSDIO_ALP_AVAIL 0x40
-/* Status: HT is ready */
-#define SBSDIO_HT_AVAIL 0x80
-
-#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
-#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
-#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
-#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
-
-#define SBSDIO_CLKAV(regval, alponly) \
- (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
-
-/* direct(mapped) cis space */
-
-/* MAPPED common CIS address */
-#define SBSDIO_CIS_BASE_COMMON 0x1000
-/* maximum bytes in one CIS */
-#define SBSDIO_CIS_SIZE_LIMIT 0x200
-/* cis offset addr is < 17 bits */
-#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF
-
-/* manfid tuple length, include tuple, link bytes */
-#define SBSDIO_CIS_MANFID_TUPLE_LEN 6
-
-/* intstatus */
-#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
-#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
-#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */
-#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */
-#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */
-#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */
-#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */
-#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */
-#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */
-#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */
-#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */
-#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */
-#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */
-#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */
-#define I_PC (1 << 10) /* descriptor error */
-#define I_PD (1 << 11) /* data error */
-#define I_DE (1 << 12) /* Descriptor protocol Error */
-#define I_RU (1 << 13) /* Receive descriptor Underflow */
-#define I_RO (1 << 14) /* Receive fifo Overflow */
-#define I_XU (1 << 15) /* Transmit fifo Underflow */
-#define I_RI (1 << 16) /* Receive Interrupt */
-#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */
-#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */
-#define I_XI (1 << 24) /* Transmit Interrupt */
-#define I_RF_TERM (1 << 25) /* Read Frame Terminate */
-#define I_WF_TERM (1 << 26) /* Write Frame Terminate */
-#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */
-#define I_SBINT (1 << 28) /* sbintstatus Interrupt */
-#define I_CHIPACTIVE (1 << 29) /* chip from doze to active state */
-#define I_SRESET (1 << 30) /* CCCR RES interrupt */
-#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */
-#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)
-#define I_DMA (I_RI | I_XI | I_ERRORS)
-
-/* corecontrol */
-#define CC_CISRDY (1 << 0) /* CIS Ready */
-#define CC_BPRESEN (1 << 1) /* CCCR RES signal */
-#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */
-#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation */
-#define CC_XMTDATAAVAIL_MODE (1 << 4)
-#define CC_XMTDATAAVAIL_CTRL (1 << 5)
-
-/* SDA_FRAMECTRL */
-#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */
-#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */
-#define SFC_CRC4WOOS (1 << 2) /* CRC error for write out of sync */
-#define SFC_ABORTALL (1 << 3) /* Abort all in-progress frames */
-
-/* HW frame tag */
-#define SDPCM_FRAMETAG_LEN 4 /* 2 bytes len, 2 bytes check val */
-
-/* Total length of frame header for dongle protocol */
-#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
-#define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN)
-
-/*
- * Software allocation of To SB Mailbox resources
- */
-
-/* tosbmailbox bits corresponding to intstatus bits */
-#define SMB_NAK (1 << 0) /* Frame NAK */
-#define SMB_INT_ACK (1 << 1) /* Host Interrupt ACK */
-#define SMB_USE_OOB (1 << 2) /* Use OOB Wakeup */
-#define SMB_DEV_INT (1 << 3) /* Miscellaneous Interrupt */
-
-/* tosbmailboxdata */
-#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version */
-
-/*
- * Software allocation of To Host Mailbox resources
- */
-
-/* intstatus bits */
-#define I_HMB_FC_STATE I_HMB_SW0 /* Flow Control State */
-#define I_HMB_FC_CHANGE I_HMB_SW1 /* Flow Control State Changed */
-#define I_HMB_FRAME_IND I_HMB_SW2 /* Frame Indication */
-#define I_HMB_HOST_INT I_HMB_SW3 /* Miscellaneous Interrupt */
-
-/* tohostmailboxdata */
-#define HMB_DATA_NAKHANDLED 1 /* retransmit NAK'd frame */
-#define HMB_DATA_DEVREADY 2 /* talk to host after enable */
-#define HMB_DATA_FC 4 /* per prio flowcontrol update flag */
-#define HMB_DATA_FWREADY 8 /* fw ready for protocol activity */
-
-#define HMB_DATA_FCDATA_MASK 0xff000000
-#define HMB_DATA_FCDATA_SHIFT 24
-
-#define HMB_DATA_VERSION_MASK 0x00ff0000
-#define HMB_DATA_VERSION_SHIFT 16
-
-/*
- * Software-defined protocol header
- */
-
-/* Current protocol version */
-#define SDPCM_PROT_VERSION 4
-
-/* SW frame header */
-#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff)
-
-#define SDPCM_CHANNEL_MASK 0x00000f00
-#define SDPCM_CHANNEL_SHIFT 8
-#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f)
-
-#define SDPCM_NEXTLEN_OFFSET 2
-
-/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
-#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */
-#define SDPCM_DOFFSET_VALUE(p) (((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
-#define SDPCM_DOFFSET_MASK 0xff000000
-#define SDPCM_DOFFSET_SHIFT 24
-#define SDPCM_FCMASK_OFFSET 4 /* Flow control */
-#define SDPCM_FCMASK_VALUE(p) (((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
-#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */
-#define SDPCM_WINDOW_VALUE(p) (((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
-
-#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */
-
-/* logical channel numbers */
-#define SDPCM_CONTROL_CHANNEL 0 /* Control channel Id */
-#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */
-#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */
-#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets */
-#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */
-
-#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for 8bit frame seq */
-
-#define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80)
-
-/*
- * Shared structure between dongle and the host.
- * The structure contains pointers to trap or assert information.
- */
-#define SDPCM_SHARED_VERSION 0x0002
-#define SDPCM_SHARED_VERSION_MASK 0x00FF
-#define SDPCM_SHARED_ASSERT_BUILT 0x0100
-#define SDPCM_SHARED_ASSERT 0x0200
-#define SDPCM_SHARED_TRAP 0x0400
-
-/* Space for header read, limit for data packets */
-#define MAX_HDR_READ (1 << 6)
-#define MAX_RX_DATASZ 2048
-
-/* Maximum milliseconds to wait for F2 to come up */
-#define BRCMF_WAIT_F2RDY 3000
-
-/* Bump up limit on waiting for HT to account for first startup;
- * if the image is doing a CRC calculation before programming the PMU
- * for HT availability, it could take a couple hundred ms more, so
- * max out at a 1 second (1000000us).
- */
-#undef PMU_MAX_TRANSITION_DLY
-#define PMU_MAX_TRANSITION_DLY 1000000
-
-/* Value for ChipClockCSR during initial setup */
-#define BRCMF_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | \
- SBSDIO_ALP_AVAIL_REQ)
-
-/* Flags for SDH calls */
-#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
-
-/* sbimstate */
-#define SBIM_IBE 0x20000 /* inbanderror */
-#define SBIM_TO 0x40000 /* timeout */
-#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */
-#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */
-
-/* sbtmstatelow */
-
-/* reset */
-#define SBTML_RESET 0x0001
-/* reject field */
-#define SBTML_REJ_MASK 0x0006
-/* reject */
-#define SBTML_REJ 0x0002
-/* temporary reject, for error recovery */
-#define SBTML_TMPREJ 0x0004
-
-/* Shift to locate the SI control flags in sbtml */
-#define SBTML_SICF_SHIFT 16
-
-/* sbtmstatehigh */
-#define SBTMH_SERR 0x0001 /* serror */
-#define SBTMH_INT 0x0002 /* interrupt */
-#define SBTMH_BUSY 0x0004 /* busy */
-#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */
-
-/* Shift to locate the SI status flags in sbtmh */
-#define SBTMH_SISF_SHIFT 16
-
-/* sbidlow */
-#define SBIDL_INIT 0x80 /* initiator */
-
-/* sbidhigh */
-#define SBIDH_RC_MASK 0x000f /* revision code */
-#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */
-#define SBIDH_RCE_SHIFT 8
-#define SBCOREREV(sbidh) \
- ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | \
- ((sbidh) & SBIDH_RC_MASK))
-#define SBIDH_CC_MASK 0x8ff0 /* core code */
-#define SBIDH_CC_SHIFT 4
-#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
-#define SBIDH_VC_SHIFT 16
-
-/*
- * Conversion of 802.1D priority to precedence level
- */
-static uint prio2prec(u32 prio)
-{
- return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
- (prio^2) : prio;
-}
-
-/*
- * Core reg address translation.
- * Both macro's returns a 32 bits byte address on the backplane bus.
- */
-#define CORE_CC_REG(base, field) \
- (base + offsetof(struct chipcregs, field))
-#define CORE_BUS_REG(base, field) \
- (base + offsetof(struct sdpcmd_regs, field))
-#define CORE_SB(base, field) \
- (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
-
-/* core registers */
-struct sdpcmd_regs {
- u32 corecontrol; /* 0x00, rev8 */
- u32 corestatus; /* rev8 */
- u32 PAD[1];
- u32 biststatus; /* rev8 */
-
- /* PCMCIA access */
- u16 pcmciamesportaladdr; /* 0x010, rev8 */
- u16 PAD[1];
- u16 pcmciamesportalmask; /* rev8 */
- u16 PAD[1];
- u16 pcmciawrframebc; /* rev8 */
- u16 PAD[1];
- u16 pcmciaunderflowtimer; /* rev8 */
- u16 PAD[1];
-
- /* interrupt */
- u32 intstatus; /* 0x020, rev8 */
- u32 hostintmask; /* rev8 */
- u32 intmask; /* rev8 */
- u32 sbintstatus; /* rev8 */
- u32 sbintmask; /* rev8 */
- u32 funcintmask; /* rev4 */
- u32 PAD[2];
- u32 tosbmailbox; /* 0x040, rev8 */
- u32 tohostmailbox; /* rev8 */
- u32 tosbmailboxdata; /* rev8 */
- u32 tohostmailboxdata; /* rev8 */
-
- /* synchronized access to registers in SDIO clock domain */
- u32 sdioaccess; /* 0x050, rev8 */
- u32 PAD[3];
-
- /* PCMCIA frame control */
- u8 pcmciaframectrl; /* 0x060, rev8 */
- u8 PAD[3];
- u8 pcmciawatermark; /* rev8 */
- u8 PAD[155];
-
- /* interrupt batching control */
- u32 intrcvlazy; /* 0x100, rev8 */
- u32 PAD[3];
-
- /* counters */
- u32 cmd52rd; /* 0x110, rev8 */
- u32 cmd52wr; /* rev8 */
- u32 cmd53rd; /* rev8 */
- u32 cmd53wr; /* rev8 */
- u32 abort; /* rev8 */
- u32 datacrcerror; /* rev8 */
- u32 rdoutofsync; /* rev8 */
- u32 wroutofsync; /* rev8 */
- u32 writebusy; /* rev8 */
- u32 readwait; /* rev8 */
- u32 readterm; /* rev8 */
- u32 writeterm; /* rev8 */
- u32 PAD[40];
- u32 clockctlstatus; /* rev8 */
- u32 PAD[7];
-
- u32 PAD[128]; /* DMA engines */
-
- /* SDIO/PCMCIA CIS region */
- char cis[512]; /* 0x400-0x5ff, rev6 */
-
- /* PCMCIA function control registers */
- char pcmciafcr[256]; /* 0x600-6ff, rev6 */
- u16 PAD[55];
-
- /* PCMCIA backplane access */
- u16 backplanecsr; /* 0x76E, rev6 */
- u16 backplaneaddr0; /* rev6 */
- u16 backplaneaddr1; /* rev6 */
- u16 backplaneaddr2; /* rev6 */
- u16 backplaneaddr3; /* rev6 */
- u16 backplanedata0; /* rev6 */
- u16 backplanedata1; /* rev6 */
- u16 backplanedata2; /* rev6 */
- u16 backplanedata3; /* rev6 */
- u16 PAD[31];
-
- /* sprom "size" & "blank" info */
- u16 spromstatus; /* 0x7BE, rev2 */
- u32 PAD[464];
-
- u16 PAD[0x80];
-};
-
-#ifdef BCMDBG
-/* Device console log buffer state */
-struct brcmf_console {
- uint count; /* Poll interval msec counter */
- uint log_addr; /* Log struct address (fixed) */
- struct rte_log_le log_le; /* Log struct (host copy) */
- uint bufsize; /* Size of log buffer */
- u8 *buf; /* Log buffer (host copy) */
- uint last; /* Last buffer read index */
-};
-#endif /* BCMDBG */
-
-struct sdpcm_shared {
- u32 flags;
- u32 trap_addr;
- u32 assert_exp_addr;
- u32 assert_file_addr;
- u32 assert_line;
- u32 console_addr; /* Address of struct rte_console */
- u32 msgtrace_addr;
- u8 tag[32];
-};
-
-struct sdpcm_shared_le {
- __le32 flags;
- __le32 trap_addr;
- __le32 assert_exp_addr;
- __le32 assert_file_addr;
- __le32 assert_line;
- __le32 console_addr; /* Address of struct rte_console */
- __le32 msgtrace_addr;
- u8 tag[32];
-};
-
-
-/* misc chip info needed by some of the routines */
-struct chip_info {
- u32 chip;
- u32 chiprev;
- u32 cccorebase;
- u32 ccrev;
- u32 cccaps;
- u32 buscorebase; /* 32 bits backplane bus address */
- u32 buscorerev;
- u32 buscoretype;
- u32 ramcorebase;
- u32 armcorebase;
- u32 pmurev;
- u32 ramsize;
-};
-
-/* Private data for SDIO bus interaction */
-struct brcmf_bus {
- struct brcmf_pub *drvr;
-
- struct brcmf_sdio_dev *sdiodev; /* sdio device handler */
- struct chip_info *ci; /* Chip info struct */
- char *vars; /* Variables (from CIS and/or other) */
- uint varsz; /* Size of variables buffer */
-
- u32 ramsize; /* Size of RAM in SOCRAM (bytes) */
-
- u32 hostintmask; /* Copy of Host Interrupt Mask */
- u32 intstatus; /* Intstatus bits (events) pending */
- bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */
- bool fcstate; /* State of dongle flow-control */
-
- uint blocksize; /* Block size of SDIO transfers */
- uint roundup; /* Max roundup limit */
-
- struct pktq txq; /* Queue length used for flow-control */
- u8 flowcontrol; /* per prio flow control bitmask */
- u8 tx_seq; /* Transmit sequence number (next) */
- u8 tx_max; /* Maximum transmit sequence allowed */
-
- u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
- u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
- u16 nextlen; /* Next Read Len from last header */
- u8 rx_seq; /* Receive sequence number (expected) */
- bool rxskip; /* Skip receive (awaiting NAK ACK) */
-
- uint rxbound; /* Rx frames to read before resched */
- uint txbound; /* Tx frames to send before resched */
- uint txminmax;
-
- struct sk_buff *glomd; /* Packet containing glomming descriptor */
- struct sk_buff *glom; /* Packet chain for glommed superframe */
- uint glomerr; /* Glom packet read errors */
-
- u8 *rxbuf; /* Buffer for receiving control packets */
- uint rxblen; /* Allocated length of rxbuf */
- u8 *rxctl; /* Aligned pointer into rxbuf */
- u8 *databuf; /* Buffer for receiving big glom packet */
- u8 *dataptr; /* Aligned pointer into databuf */
- uint rxlen; /* Length of valid data in buffer */
-
- u8 sdpcm_ver; /* Bus protocol reported by dongle */
-
- bool intr; /* Use interrupts */
- bool poll; /* Use polling */
- bool ipend; /* Device interrupt is pending */
- uint intrcount; /* Count of device interrupt callbacks */
- uint lastintrs; /* Count as of last watchdog timer */
- uint spurious; /* Count of spurious interrupts */
- uint pollrate; /* Ticks between device polls */
- uint polltick; /* Tick counter */
- uint pollcnt; /* Count of active polls */
-
-#ifdef BCMDBG
- uint console_interval;
- struct brcmf_console console; /* Console output polling support */
- uint console_addr; /* Console address from shared struct */
-#endif /* BCMDBG */
-
- uint regfails; /* Count of R_REG failures */
-
- uint clkstate; /* State of sd and backplane clock(s) */
- bool activity; /* Activity flag for clock down */
- s32 idletime; /* Control for activity timeout */
- s32 idlecount; /* Activity timeout counter */
- s32 idleclock; /* How to set bus driver when idle */
- s32 sd_rxchain;
- bool use_rxchain; /* If brcmf should use PKT chains */
- bool sleeping; /* Is SDIO bus sleeping? */
- bool rxflow_mode; /* Rx flow control mode */
- bool rxflow; /* Is rx flow control on */
- bool alp_only; /* Don't use HT clock (ALP only) */
-/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
- bool usebufpool;
-
- /* Some additional counters */
- uint tx_sderrs; /* Count of tx attempts with sd errors */
- uint fcqueued; /* Tx packets that got queued */
- uint rxrtx; /* Count of rtx requests (NAK to dongle) */
- uint rx_toolong; /* Receive frames too long to receive */
- uint rxc_errors; /* SDIO errors when reading control frames */
- uint rx_hdrfail; /* SDIO errors on header reads */
- uint rx_badhdr; /* Bad received headers (roosync?) */
- uint rx_badseq; /* Mismatched rx sequence number */
- uint fc_rcvd; /* Number of flow-control events received */
- uint fc_xoff; /* Number which turned on flow-control */
- uint fc_xon; /* Number which turned off flow-control */
- uint rxglomfail; /* Failed deglom attempts */
- uint rxglomframes; /* Number of glom frames (superframes) */
- uint rxglompkts; /* Number of packets from glom frames */
- uint f2rxhdrs; /* Number of header reads */
- uint f2rxdata; /* Number of frame data reads */
- uint f2txdata; /* Number of f2 frame writes */
- uint f1regdata; /* Number of f1 register accesses */
-
- u8 *ctrl_frame_buf;
- u32 ctrl_frame_len;
- bool ctrl_frame_stat;
-
- spinlock_t txqlock;
- wait_queue_head_t ctrl_wait;
- wait_queue_head_t dcmd_resp_wait;
-
- struct timer_list timer;
- struct completion watchdog_wait;
- struct task_struct *watchdog_tsk;
- bool wd_timer_valid;
- uint save_ms;
-
- struct task_struct *dpc_tsk;
- struct completion dpc_wait;
-
- struct semaphore sdsem;
-
- const char *fw_name;
- const struct firmware *firmware;
- const char *nv_name;
- u32 fw_ptr;
-};
-
-struct sbconfig {
- u32 PAD[2];
- u32 sbipsflag; /* initiator port ocp slave flag */
- u32 PAD[3];
- u32 sbtpsflag; /* target port ocp slave flag */
- u32 PAD[11];
- u32 sbtmerrloga; /* (sonics >= 2.3) */
- u32 PAD;
- u32 sbtmerrlog; /* (sonics >= 2.3) */
- u32 PAD[3];
- u32 sbadmatch3; /* address match3 */
- u32 PAD;
- u32 sbadmatch2; /* address match2 */
- u32 PAD;
- u32 sbadmatch1; /* address match1 */
- u32 PAD[7];
- u32 sbimstate; /* initiator agent state */
- u32 sbintvec; /* interrupt mask */
- u32 sbtmstatelow; /* target state */
- u32 sbtmstatehigh; /* target state */
- u32 sbbwa0; /* bandwidth allocation table0 */
- u32 PAD;
- u32 sbimconfiglow; /* initiator configuration */
- u32 sbimconfighigh; /* initiator configuration */
- u32 sbadmatch0; /* address match0 */
- u32 PAD;
- u32 sbtmconfiglow; /* target configuration */
- u32 sbtmconfighigh; /* target configuration */
- u32 sbbconfig; /* broadcast configuration */
- u32 PAD;
- u32 sbbstate; /* broadcast state */
- u32 PAD[3];
- u32 sbactcnfg; /* activate configuration */
- u32 PAD[3];
- u32 sbflagst; /* current sbflags */
- u32 PAD[3];
- u32 sbidlow; /* identification */
- u32 sbidhigh; /* identification */
-};
-
-/* clkstate */
-#define CLK_NONE 0
-#define CLK_SDONLY 1
-#define CLK_PENDING 2 /* Not used yet */
-#define CLK_AVAIL 3
-
-#ifdef BCMDBG
-static int qcount[NUMPRIO];
-static int tx_packets[NUMPRIO];
-#endif /* BCMDBG */
-
-#define SDIO_DRIVE_STRENGTH 6 /* in milliamps */
-
-#define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL)
-
-/* Retry count for register access failures */
-static const uint retry_limit = 2;
-
-/* Limit on rounding up frames */
-static const uint max_roundup = 512;
-
-#define ALIGNMENT 4
-
-static void pkt_align(struct sk_buff *p, int len, int align)
-{
- uint datalign;
- datalign = (unsigned long)(p->data);
- datalign = roundup(datalign, (align)) - datalign;
- if (datalign)
- skb_pull(p, datalign);
- __skb_trim(p, len);
-}
-
-/* To check if there's window offered */
-static bool data_ok(struct brcmf_bus *bus)
-{
- return (u8)(bus->tx_max - bus->tx_seq) != 0 &&
- ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
-}
-
-/*
- * Reads a register in the SDIO hardware block. This block occupies a series of
- * adresses on the 32 bit backplane bus.
- */
-static void
-r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar)
-{
- *retryvar = 0;
- do {
- *regvar = brcmf_sdcard_reg_read(bus->sdiodev,
- bus->ci->buscorebase + reg_offset, sizeof(u32));
- } while (brcmf_sdcard_regfail(bus->sdiodev) &&
- (++(*retryvar) <= retry_limit));
- if (*retryvar) {
- bus->regfails += (*retryvar-1);
- if (*retryvar > retry_limit) {
- brcmf_dbg(ERROR, "FAILED READ %Xh\n", reg_offset);
- *regvar = 0;
- }
- }
-}
-
-static void
-w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar)
-{
- *retryvar = 0;
- do {
- brcmf_sdcard_reg_write(bus->sdiodev,
- bus->ci->buscorebase + reg_offset,
- sizeof(u32), regval);
- } while (brcmf_sdcard_regfail(bus->sdiodev) &&
- (++(*retryvar) <= retry_limit));
- if (*retryvar) {
- bus->regfails += (*retryvar-1);
- if (*retryvar > retry_limit)
- brcmf_dbg(ERROR, "FAILED REGISTER WRITE %Xh\n",
- reg_offset);
- }
-}
-
-#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
-
-#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
-
-/* Packet free applicable unconditionally for sdio and sdspi.
- * Conditional if bufpool was present for gspi bus.
- */
-static void brcmf_sdbrcm_pktfree2(struct brcmf_bus *bus, struct sk_buff *pkt)
-{
- if (bus->usebufpool)
- brcmu_pkt_buf_free_skb(pkt);
-}
-
-/* Turn backplane clock on or off */
-static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok)
-{
- int err;
- u8 clkctl, clkreq, devctl;
- unsigned long timeout;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- clkctl = 0;
-
- if (on) {
- /* Request HT Avail */
- clkreq =
- bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
-
- if ((bus->ci->chip == BCM4329_CHIP_ID)
- && (bus->ci->chiprev == 0))
- clkreq |= SBSDIO_FORCE_ALP;
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
- if (err) {
- brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
- return -EBADE;
- }
-
- if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID)
- && (bus->ci->buscorerev == 9))) {
- u32 dummy, retries;
- r_sdreg32(bus, &dummy,
- offsetof(struct sdpcmd_regs, clockctlstatus),
- &retries);
- }
-
- /* Check current status */
- clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, &err);
- if (err) {
- brcmf_dbg(ERROR, "HT Avail read error: %d\n", err);
- return -EBADE;
- }
-
- /* Go to pending and await interrupt if appropriate */
- if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
- /* Allow only clock-available interrupt */
- devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, &err);
- if (err) {
- brcmf_dbg(ERROR, "Devctl error setting CA: %d\n",
- err);
- return -EBADE;
- }
-
- devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, devctl, &err);
- brcmf_dbg(INFO, "CLKCTL: set PENDING\n");
- bus->clkstate = CLK_PENDING;
-
- return 0;
- } else if (bus->clkstate == CLK_PENDING) {
- /* Cancel CA-only interrupt filter */
- devctl =
- brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, &err);
- devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, devctl, &err);
- }
-
- /* Otherwise, wait here (polling) for HT Avail */
- timeout = jiffies +
- msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
- while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
- clkctl = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR,
- &err);
- if (time_after(jiffies, timeout))
- break;
- else
- usleep_range(5000, 10000);
- }
- if (err) {
- brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
- return -EBADE;
- }
- if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
- brcmf_dbg(ERROR, "HT Avail timeout (%d): clkctl 0x%02x\n",
- PMU_MAX_TRANSITION_DLY, clkctl);
- return -EBADE;
- }
-
- /* Mark clock available */
- bus->clkstate = CLK_AVAIL;
- brcmf_dbg(INFO, "CLKCTL: turned ON\n");
-
-#if defined(BCMDBG)
- if (bus->alp_only != true) {
- if (SBSDIO_ALPONLY(clkctl))
- brcmf_dbg(ERROR, "HT Clock should be on\n");
- }
-#endif /* defined (BCMDBG) */
-
- bus->activity = true;
- } else {
- clkreq = 0;
-
- if (bus->clkstate == CLK_PENDING) {
- /* Cancel CA-only interrupt filter */
- devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, &err);
- devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, devctl, &err);
- }
-
- bus->clkstate = CLK_SDONLY;
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
- brcmf_dbg(INFO, "CLKCTL: turned OFF\n");
- if (err) {
- brcmf_dbg(ERROR, "Failed access turning clock off: %d\n",
- err);
- return -EBADE;
- }
- }
- return 0;
-}
-
-/* Change idle/active SD state */
-static int brcmf_sdbrcm_sdclk(struct brcmf_bus *bus, bool on)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- if (on)
- bus->clkstate = CLK_SDONLY;
- else
- bus->clkstate = CLK_NONE;
-
- return 0;
-}
-
-/* Transition SD and backplane clock readiness */
-static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok)
-{
-#ifdef BCMDBG
- uint oldstate = bus->clkstate;
-#endif /* BCMDBG */
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Early exit if we're already there */
- if (bus->clkstate == target) {
- if (target == CLK_AVAIL) {
- brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
- bus->activity = true;
- }
- return 0;
- }
-
- switch (target) {
- case CLK_AVAIL:
- /* Make sure SD clock is available */
- if (bus->clkstate == CLK_NONE)
- brcmf_sdbrcm_sdclk(bus, true);
- /* Now request HT Avail on the backplane */
- brcmf_sdbrcm_htclk(bus, true, pendok);
- brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
- bus->activity = true;
- break;
-
- case CLK_SDONLY:
- /* Remove HT request, or bring up SD clock */
- if (bus->clkstate == CLK_NONE)
- brcmf_sdbrcm_sdclk(bus, true);
- else if (bus->clkstate == CLK_AVAIL)
- brcmf_sdbrcm_htclk(bus, false, false);
- else
- brcmf_dbg(ERROR, "request for %d -> %d\n",
- bus->clkstate, target);
- brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
- break;
-
- case CLK_NONE:
- /* Make sure to remove HT request */
- if (bus->clkstate == CLK_AVAIL)
- brcmf_sdbrcm_htclk(bus, false, false);
- /* Now remove the SD clock */
- brcmf_sdbrcm_sdclk(bus, false);
- brcmf_sdbrcm_wd_timer(bus, 0);
- break;
- }
-#ifdef BCMDBG
- brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate);
-#endif /* BCMDBG */
-
- return 0;
-}
-
-static int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep)
-{
- uint retries = 0;
-
- brcmf_dbg(INFO, "request %s (currently %s)\n",
- sleep ? "SLEEP" : "WAKE",
- bus->sleeping ? "SLEEP" : "WAKE");
-
- /* Done if we're already in the requested state */
- if (sleep == bus->sleeping)
- return 0;
-
- /* Going to sleep: set the alarm and turn off the lights... */
- if (sleep) {
- /* Don't sleep if something is pending */
- if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
- return -EBUSY;
-
- /* Make sure the controller has the bus up */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
-
- /* Tell device to start using OOB wakeup */
- w_sdreg32(bus, SMB_USE_OOB,
- offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
- if (retries > retry_limit)
- brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
-
- /* Turn off our contribution to the HT clock request */
- brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR,
- SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
-
- /* Isolate the bus */
- if (bus->ci->chip != BCM4329_CHIP_ID) {
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL,
- SBSDIO_DEVCTL_PADS_ISO, NULL);
- }
-
- /* Change state */
- bus->sleeping = true;
-
- } else {
- /* Waking up: bus power up is ok, set local state */
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
-
- /* Force pad isolation off if possible
- (in case power never toggled) */
- if ((bus->ci->buscoretype == PCMCIA_CORE_ID)
- && (bus->ci->buscorerev >= 10))
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, 0, NULL);
-
- /* Make sure the controller has the bus up */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
-
- /* Send misc interrupt to indicate OOB not needed */
- w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata),
- &retries);
- if (retries <= retry_limit)
- w_sdreg32(bus, SMB_DEV_INT,
- offsetof(struct sdpcmd_regs, tosbmailbox),
- &retries);
-
- if (retries > retry_limit)
- brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
-
- /* Make sure we have SD bus access */
- brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
-
- /* Change state */
- bus->sleeping = false;
- }
-
- return 0;
-}
-
-static void bus_wake(struct brcmf_bus *bus)
-{
- if (bus->sleeping)
- brcmf_sdbrcm_bussleep(bus, false);
-}
-
-static u32 brcmf_sdbrcm_hostmail(struct brcmf_bus *bus)
-{
- u32 intstatus = 0;
- u32 hmb_data;
- u8 fcbits;
- uint retries = 0;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Read mailbox data and ack that we did so */
- r_sdreg32(bus, &hmb_data,
- offsetof(struct sdpcmd_regs, tohostmailboxdata), &retries);
-
- if (retries <= retry_limit)
- w_sdreg32(bus, SMB_INT_ACK,
- offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
- bus->f1regdata += 2;
-
- /* Dongle recomposed rx frames, accept them again */
- if (hmb_data & HMB_DATA_NAKHANDLED) {
- brcmf_dbg(INFO, "Dongle reports NAK handled, expect rtx of %d\n",
- bus->rx_seq);
- if (!bus->rxskip)
- brcmf_dbg(ERROR, "unexpected NAKHANDLED!\n");
-
- bus->rxskip = false;
- intstatus |= I_HMB_FRAME_IND;
- }
-
- /*
- * DEVREADY does not occur with gSPI.
- */
- if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
- bus->sdpcm_ver =
- (hmb_data & HMB_DATA_VERSION_MASK) >>
- HMB_DATA_VERSION_SHIFT;
- if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
- brcmf_dbg(ERROR, "Version mismatch, dongle reports %d, "
- "expecting %d\n",
- bus->sdpcm_ver, SDPCM_PROT_VERSION);
- else
- brcmf_dbg(INFO, "Dongle ready, protocol version %d\n",
- bus->sdpcm_ver);
- }
-
- /*
- * Flow Control has been moved into the RX headers and this out of band
- * method isn't used any more.
- * remaining backward compatible with older dongles.
- */
- if (hmb_data & HMB_DATA_FC) {
- fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
- HMB_DATA_FCDATA_SHIFT;
-
- if (fcbits & ~bus->flowcontrol)
- bus->fc_xoff++;
-
- if (bus->flowcontrol & ~fcbits)
- bus->fc_xon++;
-
- bus->fc_rcvd++;
- bus->flowcontrol = fcbits;
- }
-
- /* Shouldn't be any others */
- if (hmb_data & ~(HMB_DATA_DEVREADY |
- HMB_DATA_NAKHANDLED |
- HMB_DATA_FC |
- HMB_DATA_FWREADY |
- HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK))
- brcmf_dbg(ERROR, "Unknown mailbox data content: 0x%02x\n",
- hmb_data);
-
- return intstatus;
-}
-
-static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx)
-{
- uint retries = 0;
- u16 lastrbc;
- u8 hi, lo;
- int err;
-
- brcmf_dbg(ERROR, "%sterminate frame%s\n",
- abort ? "abort command, " : "",
- rtx ? ", send NAK" : "");
-
- if (abort)
- brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_FRAMECTRL,
- SFC_RF_TERM, &err);
- bus->f1regdata++;
-
- /* Wait until the packet has been flushed (device/FIFO stable) */
- for (lastrbc = retries = 0xffff; retries > 0; retries--) {
- hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_RFRAMEBCHI, NULL);
- lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_RFRAMEBCLO, NULL);
- bus->f1regdata += 2;
-
- if ((hi == 0) && (lo == 0))
- break;
-
- if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
- brcmf_dbg(ERROR, "count growing: last 0x%04x now 0x%04x\n",
- lastrbc, (hi << 8) + lo);
- }
- lastrbc = (hi << 8) + lo;
- }
-
- if (!retries)
- brcmf_dbg(ERROR, "count never zeroed: last 0x%04x\n", lastrbc);
- else
- brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries);
-
- if (rtx) {
- bus->rxrtx++;
- w_sdreg32(bus, SMB_NAK,
- offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
-
- bus->f1regdata++;
- if (retries <= retry_limit)
- bus->rxskip = true;
- }
-
- /* Clear partial in any case */
- bus->nextlen = 0;
-
- /* If we can't reach the device, signal failure */
- if (err || brcmf_sdcard_regfail(bus->sdiodev))
- bus->drvr->busstate = BRCMF_BUS_DOWN;
-}
-
-static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
-{
- u16 dlen, totlen;
- u8 *dptr, num = 0;
-
- u16 sublen, check;
- struct sk_buff *pfirst, *plast, *pnext, *save_pfirst;
-
- int errcode;
- u8 chan, seq, doff, sfdoff;
- u8 txmax;
-
- int ifidx = 0;
- bool usechain = bus->use_rxchain;
-
- /* If packets, issue read(s) and send up packet chain */
- /* Return sequence numbers consumed? */
-
- brcmf_dbg(TRACE, "start: glomd %p glom %p\n", bus->glomd, bus->glom);
-
- /* If there's a descriptor, generate the packet chain */
- if (bus->glomd) {
- pfirst = plast = pnext = NULL;
- dlen = (u16) (bus->glomd->len);
- dptr = bus->glomd->data;
- if (!dlen || (dlen & 1)) {
- brcmf_dbg(ERROR, "bad glomd len(%d), ignore descriptor\n",
- dlen);
- dlen = 0;
- }
-
- for (totlen = num = 0; dlen; num++) {
- /* Get (and move past) next length */
- sublen = get_unaligned_le16(dptr);
- dlen -= sizeof(u16);
- dptr += sizeof(u16);
- if ((sublen < SDPCM_HDRLEN) ||
- ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
- brcmf_dbg(ERROR, "descriptor len %d bad: %d\n",
- num, sublen);
- pnext = NULL;
- break;
- }
- if (sublen % BRCMF_SDALIGN) {
- brcmf_dbg(ERROR, "sublen %d not multiple of %d\n",
- sublen, BRCMF_SDALIGN);
- usechain = false;
- }
- totlen += sublen;
-
- /* For last frame, adjust read len so total
- is a block multiple */
- if (!dlen) {
- sublen +=
- (roundup(totlen, bus->blocksize) - totlen);
- totlen = roundup(totlen, bus->blocksize);
- }
-
- /* Allocate/chain packet for next subframe */
- pnext = brcmu_pkt_buf_get_skb(sublen + BRCMF_SDALIGN);
- if (pnext == NULL) {
- brcmf_dbg(ERROR, "bcm_pkt_buf_get_skb failed, num %d len %d\n",
- num, sublen);
- break;
- }
- if (!pfirst) {
- pfirst = plast = pnext;
- } else {
- plast->next = pnext;
- plast = pnext;
- }
-
- /* Adhere to start alignment requirements */
- pkt_align(pnext, sublen, BRCMF_SDALIGN);
- }
-
- /* If all allocations succeeded, save packet chain
- in bus structure */
- if (pnext) {
- brcmf_dbg(GLOM, "allocated %d-byte packet chain for %d subframes\n",
- totlen, num);
- if (BRCMF_GLOM_ON() && bus->nextlen &&
- totlen != bus->nextlen) {
- brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n",
- bus->nextlen, totlen, rxseq);
- }
- bus->glom = pfirst;
- pfirst = pnext = NULL;
- } else {
- if (pfirst)
- brcmu_pkt_buf_free_skb(pfirst);
- bus->glom = NULL;
- num = 0;
- }
-
- /* Done with descriptor packet */
- brcmu_pkt_buf_free_skb(bus->glomd);
- bus->glomd = NULL;
- bus->nextlen = 0;
- }
-
- /* Ok -- either we just generated a packet chain,
- or had one from before */
- if (bus->glom) {
- if (BRCMF_GLOM_ON()) {
- brcmf_dbg(GLOM, "try superframe read, packet chain:\n");
- for (pnext = bus->glom; pnext; pnext = pnext->next) {
- brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n",
- pnext, (u8 *) (pnext->data),
- pnext->len, pnext->len);
- }
- }
-
- pfirst = bus->glom;
- dlen = (u16) brcmu_pkttotlen(pfirst);
-
- /* Do an SDIO read for the superframe. Configurable iovar to
- * read directly into the chained packet, or allocate a large
- * packet and and copy into the chain.
- */
- if (usechain) {
- errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
- bus->sdiodev->sbwad,
- SDIO_FUNC_2,
- F2SYNC, (u8 *) pfirst->data, dlen,
- pfirst);
- } else if (bus->dataptr) {
- errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
- bus->sdiodev->sbwad,
- SDIO_FUNC_2,
- F2SYNC, bus->dataptr, dlen,
- NULL);
- sublen = (u16) brcmu_pktfrombuf(pfirst, 0, dlen,
- bus->dataptr);
- if (sublen != dlen) {
- brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n",
- dlen, sublen);
- errcode = -1;
- }
- pnext = NULL;
- } else {
- brcmf_dbg(ERROR, "COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
- dlen);
- errcode = -1;
- }
- bus->f2rxdata++;
-
- /* On failure, kill the superframe, allow a couple retries */
- if (errcode < 0) {
- brcmf_dbg(ERROR, "glom read of %d bytes failed: %d\n",
- dlen, errcode);
- bus->drvr->rx_errors++;
-
- if (bus->glomerr++ < 3) {
- brcmf_sdbrcm_rxfail(bus, true, true);
- } else {
- bus->glomerr = 0;
- brcmf_sdbrcm_rxfail(bus, true, false);
- brcmu_pkt_buf_free_skb(bus->glom);
- bus->rxglomfail++;
- bus->glom = NULL;
- }
- return 0;
- }
-#ifdef BCMDBG
- if (BRCMF_GLOM_ON()) {
- printk(KERN_DEBUG "SUPERFRAME:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- pfirst->data, min_t(int, pfirst->len, 48));
- }
-#endif
-
- /* Validate the superframe header */
- dptr = (u8 *) (pfirst->data);
- sublen = get_unaligned_le16(dptr);
- check = get_unaligned_le16(dptr + sizeof(u16));
-
- chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
- seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
- bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
- if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
- brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n",
- bus->nextlen, seq);
- bus->nextlen = 0;
- }
- doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
- txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
-
- errcode = 0;
- if ((u16)~(sublen ^ check)) {
- brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n",
- sublen, check);
- errcode = -1;
- } else if (roundup(sublen, bus->blocksize) != dlen) {
- brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n",
- sublen, roundup(sublen, bus->blocksize),
- dlen);
- errcode = -1;
- } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
- SDPCM_GLOM_CHANNEL) {
- brcmf_dbg(ERROR, "(superframe): bad channel %d\n",
- SDPCM_PACKET_CHANNEL(
- &dptr[SDPCM_FRAMETAG_LEN]));
- errcode = -1;
- } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
- brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n");
- errcode = -1;
- } else if ((doff < SDPCM_HDRLEN) ||
- (doff > (pfirst->len - SDPCM_HDRLEN))) {
- brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n",
- doff, sublen, pfirst->len, SDPCM_HDRLEN);
- errcode = -1;
- }
-
- /* Check sequence number of superframe SW header */
- if (rxseq != seq) {
- brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n",
- seq, rxseq);
- bus->rx_badseq++;
- rxseq = seq;
- }
-
- /* Check window for sanity */
- if ((u8) (txmax - bus->tx_seq) > 0x40) {
- brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
- txmax, bus->tx_seq);
- txmax = bus->tx_seq + 2;
- }
- bus->tx_max = txmax;
-
- /* Remove superframe header, remember offset */
- skb_pull(pfirst, doff);
- sfdoff = doff;
-
- /* Validate all the subframe headers */
- for (num = 0, pnext = pfirst; pnext && !errcode;
- num++, pnext = pnext->next) {
- dptr = (u8 *) (pnext->data);
- dlen = (u16) (pnext->len);
- sublen = get_unaligned_le16(dptr);
- check = get_unaligned_le16(dptr + sizeof(u16));
- chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
- doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
-#ifdef BCMDBG
- if (BRCMF_GLOM_ON()) {
- printk(KERN_DEBUG "subframe:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- dptr, 32);
- }
-#endif
-
- if ((u16)~(sublen ^ check)) {
- brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
- num, sublen, check);
- errcode = -1;
- } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
- brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n",
- num, sublen, dlen);
- errcode = -1;
- } else if ((chan != SDPCM_DATA_CHANNEL) &&
- (chan != SDPCM_EVENT_CHANNEL)) {
- brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n",
- num, chan);
- errcode = -1;
- } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
- brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n",
- num, doff, sublen, SDPCM_HDRLEN);
- errcode = -1;
- }
- }
-
- if (errcode) {
- /* Terminate frame on error, request
- a couple retries */
- if (bus->glomerr++ < 3) {
- /* Restore superframe header space */
- skb_push(pfirst, sfdoff);
- brcmf_sdbrcm_rxfail(bus, true, true);
- } else {
- bus->glomerr = 0;
- brcmf_sdbrcm_rxfail(bus, true, false);
- brcmu_pkt_buf_free_skb(bus->glom);
- bus->rxglomfail++;
- bus->glom = NULL;
- }
- bus->nextlen = 0;
- return 0;
- }
-
- /* Basic SD framing looks ok - process each packet (header) */
- save_pfirst = pfirst;
- bus->glom = NULL;
- plast = NULL;
-
- for (num = 0; pfirst; rxseq++, pfirst = pnext) {
- pnext = pfirst->next;
- pfirst->next = NULL;
-
- dptr = (u8 *) (pfirst->data);
- sublen = get_unaligned_le16(dptr);
- chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
- seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
- doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
-
- brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n",
- num, pfirst, pfirst->data,
- pfirst->len, sublen, chan, seq);
-
- /* precondition: chan == SDPCM_DATA_CHANNEL ||
- chan == SDPCM_EVENT_CHANNEL */
-
- if (rxseq != seq) {
- brcmf_dbg(GLOM, "rx_seq %d, expected %d\n",
- seq, rxseq);
- bus->rx_badseq++;
- rxseq = seq;
- }
-#ifdef BCMDBG
- if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
- printk(KERN_DEBUG "Rx Subframe Data:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- dptr, dlen);
- }
-#endif
-
- __skb_trim(pfirst, sublen);
- skb_pull(pfirst, doff);
-
- if (pfirst->len == 0) {
- brcmu_pkt_buf_free_skb(pfirst);
- if (plast)
- plast->next = pnext;
- else
- save_pfirst = pnext;
-
- continue;
- } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx,
- pfirst) != 0) {
- brcmf_dbg(ERROR, "rx protocol error\n");
- bus->drvr->rx_errors++;
- brcmu_pkt_buf_free_skb(pfirst);
- if (plast)
- plast->next = pnext;
- else
- save_pfirst = pnext;
-
- continue;
- }
-
- /* this packet will go up, link back into
- chain and count it */
- pfirst->next = pnext;
- plast = pfirst;
- num++;
-
-#ifdef BCMDBG
- if (BRCMF_GLOM_ON()) {
- brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
- num, pfirst, pfirst->data,
- pfirst->len, pfirst->next,
- pfirst->prev);
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- pfirst->data,
- min_t(int, pfirst->len, 32));
- }
-#endif /* BCMDBG */
- }
- if (num) {
- up(&bus->sdsem);
- brcmf_rx_frame(bus->drvr, ifidx, save_pfirst, num);
- down(&bus->sdsem);
- }
-
- bus->rxglomframes++;
- bus->rxglompkts += num;
- }
- return num;
-}
-
-static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_bus *bus, uint *condition,
- bool *pending)
-{
- DECLARE_WAITQUEUE(wait, current);
- int timeout = msecs_to_jiffies(DCMD_RESP_TIMEOUT);
-
- /* Wait until control frame is available */
- add_wait_queue(&bus->dcmd_resp_wait, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- while (!(*condition) && (!signal_pending(current) && timeout))
- timeout = schedule_timeout(timeout);
-
- if (signal_pending(current))
- *pending = true;
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&bus->dcmd_resp_wait, &wait);
-
- return timeout;
-}
-
-static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_bus *bus)
-{
- if (waitqueue_active(&bus->dcmd_resp_wait))
- wake_up_interruptible(&bus->dcmd_resp_wait);
-
- return 0;
-}
-static void
-brcmf_sdbrcm_read_control(struct brcmf_bus *bus, u8 *hdr, uint len, uint doff)
-{
- uint rdlen, pad;
-
- int sdret;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Set rxctl for frame (w/optional alignment) */
- bus->rxctl = bus->rxbuf;
- bus->rxctl += BRCMF_FIRSTREAD;
- pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN);
- if (pad)
- bus->rxctl += (BRCMF_SDALIGN - pad);
- bus->rxctl -= BRCMF_FIRSTREAD;
-
- /* Copy the already-read portion over */
- memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD);
- if (len <= BRCMF_FIRSTREAD)
- goto gotpkt;
-
- /* Raise rdlen to next SDIO block to avoid tail command */
- rdlen = len - BRCMF_FIRSTREAD;
- if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
- pad = bus->blocksize - (rdlen % bus->blocksize);
- if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
- ((len + pad) < bus->drvr->maxctl))
- rdlen += pad;
- } else if (rdlen % BRCMF_SDALIGN) {
- rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
- }
-
- /* Satisfy length-alignment requirements */
- if (rdlen & (ALIGNMENT - 1))
- rdlen = roundup(rdlen, ALIGNMENT);
-
- /* Drop if the read is too big or it exceeds our maximum */
- if ((rdlen + BRCMF_FIRSTREAD) > bus->drvr->maxctl) {
- brcmf_dbg(ERROR, "%d-byte control read exceeds %d-byte buffer\n",
- rdlen, bus->drvr->maxctl);
- bus->drvr->rx_errors++;
- brcmf_sdbrcm_rxfail(bus, false, false);
- goto done;
- }
-
- if ((len - doff) > bus->drvr->maxctl) {
- brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
- len, len - doff, bus->drvr->maxctl);
- bus->drvr->rx_errors++;
- bus->rx_toolong++;
- brcmf_sdbrcm_rxfail(bus, false, false);
- goto done;
- }
-
- /* Read remainder of frame body into the rxctl buffer */
- sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
- bus->sdiodev->sbwad,
- SDIO_FUNC_2,
- F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen,
- NULL);
- bus->f2rxdata++;
-
- /* Control frame failures need retransmission */
- if (sdret < 0) {
- brcmf_dbg(ERROR, "read %d control bytes failed: %d\n",
- rdlen, sdret);
- bus->rxc_errors++;
- brcmf_sdbrcm_rxfail(bus, true, true);
- goto done;
- }
-
-gotpkt:
-
-#ifdef BCMDBG
- if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
- printk(KERN_DEBUG "RxCtrl:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len);
- }
-#endif
-
- /* Point to valid data and indicate its length */
- bus->rxctl += doff;
- bus->rxlen = len - doff;
-
-done:
- /* Awake any waiters */
- brcmf_sdbrcm_dcmd_resp_wake(bus);
-}
-
-/* Pad read to blocksize for efficiency */
-static void brcmf_pad(struct brcmf_bus *bus, u16 *pad, u16 *rdlen)
-{
- if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) {
- *pad = bus->blocksize - (*rdlen % bus->blocksize);
- if (*pad <= bus->roundup && *pad < bus->blocksize &&
- *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
- *rdlen += *pad;
- } else if (*rdlen % BRCMF_SDALIGN) {
- *rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN);
- }
-}
-
-static void
-brcmf_alloc_pkt_and_read(struct brcmf_bus *bus, u16 rdlen,
- struct sk_buff **pkt, u8 **rxbuf)
-{
- int sdret; /* Return code from calls */
-
- *pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN);
- if (*pkt == NULL)
- return;
-
- pkt_align(*pkt, rdlen, BRCMF_SDALIGN);
- *rxbuf = (u8 *) ((*pkt)->data);
- /* Read the entire frame */
- sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
- SDIO_FUNC_2, F2SYNC,
- *rxbuf, rdlen, *pkt);
- bus->f2rxdata++;
-
- if (sdret < 0) {
- brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n",
- rdlen, sdret);
- brcmu_pkt_buf_free_skb(*pkt);
- bus->drvr->rx_errors++;
- /* Force retry w/normal header read.
- * Don't attempt NAK for
- * gSPI
- */
- brcmf_sdbrcm_rxfail(bus, true, true);
- *pkt = NULL;
- }
-}
-
-/* Checks the header */
-static int
-brcmf_check_rxbuf(struct brcmf_bus *bus, struct sk_buff *pkt, u8 *rxbuf,
- u8 rxseq, u16 nextlen, u16 *len)
-{
- u16 check;
- bool len_consistent; /* Result of comparing readahead len and
- len from hw-hdr */
-
- memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
-
- /* Extract hardware header fields */
- *len = get_unaligned_le16(bus->rxhdr);
- check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
-
- /* All zeros means readahead info was bad */
- if (!(*len | check)) {
- brcmf_dbg(INFO, "(nextlen): read zeros in HW header???\n");
- goto fail;
- }
-
- /* Validate check bytes */
- if ((u16)~(*len ^ check)) {
- brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n",
- nextlen, *len, check);
- bus->rx_badhdr++;
- brcmf_sdbrcm_rxfail(bus, false, false);
- goto fail;
- }
-
- /* Validate frame length */
- if (*len < SDPCM_HDRLEN) {
- brcmf_dbg(ERROR, "(nextlen): HW hdr length invalid: %d\n",
- *len);
- goto fail;
- }
-
- /* Check for consistency with readahead info */
- len_consistent = (nextlen != (roundup(*len, 16) >> 4));
- if (len_consistent) {
- /* Mismatch, force retry w/normal
- header (may be >4K) */
- brcmf_dbg(ERROR, "(nextlen): mismatch, nextlen %d len %d rnd %d; expected rxseq %d\n",
- nextlen, *len, roundup(*len, 16),
- rxseq);
- brcmf_sdbrcm_rxfail(bus, true, true);
- goto fail;
- }
-
- return 0;
-
-fail:
- brcmf_sdbrcm_pktfree2(bus, pkt);
- return -EINVAL;
-}
-
-/* Return true if there may be more frames to read */
-static uint
-brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished)
-{
- u16 len, check; /* Extracted hardware header fields */
- u8 chan, seq, doff; /* Extracted software header fields */
- u8 fcbits; /* Extracted fcbits from software header */
-
- struct sk_buff *pkt; /* Packet for event or data frames */
- u16 pad; /* Number of pad bytes to read */
- u16 rdlen; /* Total number of bytes to read */
- u8 rxseq; /* Next sequence number to expect */
- uint rxleft = 0; /* Remaining number of frames allowed */
- int sdret; /* Return code from calls */
- u8 txmax; /* Maximum tx sequence offered */
- u8 *rxbuf;
- int ifidx = 0;
- uint rxcount = 0; /* Total frames read */
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Not finished unless we encounter no more frames indication */
- *finished = false;
-
- for (rxseq = bus->rx_seq, rxleft = maxframes;
- !bus->rxskip && rxleft && bus->drvr->busstate != BRCMF_BUS_DOWN;
- rxseq++, rxleft--) {
-
- /* Handle glomming separately */
- if (bus->glom || bus->glomd) {
- u8 cnt;
- brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n",
- bus->glomd, bus->glom);
- cnt = brcmf_sdbrcm_rxglom(bus, rxseq);
- brcmf_dbg(GLOM, "rxglom returned %d\n", cnt);
- rxseq += cnt - 1;
- rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
- continue;
- }
-
- /* Try doing single read if we can */
- if (bus->nextlen) {
- u16 nextlen = bus->nextlen;
- bus->nextlen = 0;
-
- rdlen = len = nextlen << 4;
- brcmf_pad(bus, &pad, &rdlen);
-
- /*
- * After the frame is received we have to
- * distinguish whether it is data
- * or non-data frame.
- */
- brcmf_alloc_pkt_and_read(bus, rdlen, &pkt, &rxbuf);
- if (pkt == NULL) {
- /* Give up on data, request rtx of events */
- brcmf_dbg(ERROR, "(nextlen): brcmf_alloc_pkt_and_read failed: len %d rdlen %d expected rxseq %d\n",
- len, rdlen, rxseq);
- continue;
- }
-
- if (brcmf_check_rxbuf(bus, pkt, rxbuf, rxseq, nextlen,
- &len) < 0)
- continue;
-
- /* Extract software header fields */
- chan = SDPCM_PACKET_CHANNEL(
- &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
- seq = SDPCM_PACKET_SEQUENCE(
- &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
- doff = SDPCM_DOFFSET_VALUE(
- &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
- txmax = SDPCM_WINDOW_VALUE(
- &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
-
- bus->nextlen =
- bus->rxhdr[SDPCM_FRAMETAG_LEN +
- SDPCM_NEXTLEN_OFFSET];
- if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
- brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
- bus->nextlen, seq);
- bus->nextlen = 0;
- }
-
- bus->drvr->rx_readahead_cnt++;
-
- /* Handle Flow Control */
- fcbits = SDPCM_FCMASK_VALUE(
- &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
-
- if (bus->flowcontrol != fcbits) {
- if (~bus->flowcontrol & fcbits)
- bus->fc_xoff++;
-
- if (bus->flowcontrol & ~fcbits)
- bus->fc_xon++;
-
- bus->fc_rcvd++;
- bus->flowcontrol = fcbits;
- }
-
- /* Check and update sequence number */
- if (rxseq != seq) {
- brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n",
- seq, rxseq);
- bus->rx_badseq++;
- rxseq = seq;
- }
-
- /* Check window for sanity */
- if ((u8) (txmax - bus->tx_seq) > 0x40) {
- brcmf_dbg(ERROR, "got unlikely tx max %d with tx_seq %d\n",
- txmax, bus->tx_seq);
- txmax = bus->tx_seq + 2;
- }
- bus->tx_max = txmax;
-
-#ifdef BCMDBG
- if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
- printk(KERN_DEBUG "Rx Data:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- rxbuf, len);
- } else if (BRCMF_HDRS_ON()) {
- printk(KERN_DEBUG "RxHdr:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- bus->rxhdr, SDPCM_HDRLEN);
- }
-#endif
-
- if (chan == SDPCM_CONTROL_CHANNEL) {
- brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n",
- seq);
- /* Force retry w/normal header read */
- bus->nextlen = 0;
- brcmf_sdbrcm_rxfail(bus, false, true);
- brcmf_sdbrcm_pktfree2(bus, pkt);
- continue;
- }
-
- /* Validate data offset */
- if ((doff < SDPCM_HDRLEN) || (doff > len)) {
- brcmf_dbg(ERROR, "(nextlen): bad data offset %d: HW len %d min %d\n",
- doff, len, SDPCM_HDRLEN);
- brcmf_sdbrcm_rxfail(bus, false, false);
- brcmf_sdbrcm_pktfree2(bus, pkt);
- continue;
- }
-
- /* All done with this one -- now deliver the packet */
- goto deliver;
- }
-
- /* Read frame header (hardware and software) */
- sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
- SDIO_FUNC_2, F2SYNC, bus->rxhdr,
- BRCMF_FIRSTREAD, NULL);
- bus->f2rxhdrs++;
-
- if (sdret < 0) {
- brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret);
- bus->rx_hdrfail++;
- brcmf_sdbrcm_rxfail(bus, true, true);
- continue;
- }
-#ifdef BCMDBG
- if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) {
- printk(KERN_DEBUG "RxHdr:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- bus->rxhdr, SDPCM_HDRLEN);
- }
-#endif
-
- /* Extract hardware header fields */
- len = get_unaligned_le16(bus->rxhdr);
- check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
-
- /* All zeros means no more frames */
- if (!(len | check)) {
- *finished = true;
- break;
- }
-
- /* Validate check bytes */
- if ((u16) ~(len ^ check)) {
- brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n",
- len, check);
- bus->rx_badhdr++;
- brcmf_sdbrcm_rxfail(bus, false, false);
- continue;
- }
-
- /* Validate frame length */
- if (len < SDPCM_HDRLEN) {
- brcmf_dbg(ERROR, "HW hdr length invalid: %d\n", len);
- continue;
- }
-
- /* Extract software header fields */
- chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
- seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
- doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
- txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
-
- /* Validate data offset */
- if ((doff < SDPCM_HDRLEN) || (doff > len)) {
- brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n",
- doff, len, SDPCM_HDRLEN, seq);
- bus->rx_badhdr++;
- brcmf_sdbrcm_rxfail(bus, false, false);
- continue;
- }
-
- /* Save the readahead length if there is one */
- bus->nextlen =
- bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
- if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
- brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
- bus->nextlen, seq);
- bus->nextlen = 0;
- }
-
- /* Handle Flow Control */
- fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
-
- if (bus->flowcontrol != fcbits) {
- if (~bus->flowcontrol & fcbits)
- bus->fc_xoff++;
-
- if (bus->flowcontrol & ~fcbits)
- bus->fc_xon++;
-
- bus->fc_rcvd++;
- bus->flowcontrol = fcbits;
- }
-
- /* Check and update sequence number */
- if (rxseq != seq) {
- brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq);
- bus->rx_badseq++;
- rxseq = seq;
- }
-
- /* Check window for sanity */
- if ((u8) (txmax - bus->tx_seq) > 0x40) {
- brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
- txmax, bus->tx_seq);
- txmax = bus->tx_seq + 2;
- }
- bus->tx_max = txmax;
-
- /* Call a separate function for control frames */
- if (chan == SDPCM_CONTROL_CHANNEL) {
- brcmf_sdbrcm_read_control(bus, bus->rxhdr, len, doff);
- continue;
- }
-
- /* precondition: chan is either SDPCM_DATA_CHANNEL,
- SDPCM_EVENT_CHANNEL, SDPCM_TEST_CHANNEL or
- SDPCM_GLOM_CHANNEL */
-
- /* Length to read */
- rdlen = (len > BRCMF_FIRSTREAD) ? (len - BRCMF_FIRSTREAD) : 0;
-
- /* May pad read to blocksize for efficiency */
- if (bus->roundup && bus->blocksize &&
- (rdlen > bus->blocksize)) {
- pad = bus->blocksize - (rdlen % bus->blocksize);
- if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
- ((rdlen + pad + BRCMF_FIRSTREAD) < MAX_RX_DATASZ))
- rdlen += pad;
- } else if (rdlen % BRCMF_SDALIGN) {
- rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
- }
-
- /* Satisfy length-alignment requirements */
- if (rdlen & (ALIGNMENT - 1))
- rdlen = roundup(rdlen, ALIGNMENT);
-
- if ((rdlen + BRCMF_FIRSTREAD) > MAX_RX_DATASZ) {
- /* Too long -- skip this frame */
- brcmf_dbg(ERROR, "too long: len %d rdlen %d\n",
- len, rdlen);
- bus->drvr->rx_errors++;
- bus->rx_toolong++;
- brcmf_sdbrcm_rxfail(bus, false, false);
- continue;
- }
-
- pkt = brcmu_pkt_buf_get_skb(rdlen +
- BRCMF_FIRSTREAD + BRCMF_SDALIGN);
- if (!pkt) {
- /* Give up on data, request rtx of events */
- brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n",
- rdlen, chan);
- bus->drvr->rx_dropped++;
- brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan));
- continue;
- }
-
- /* Leave room for what we already read, and align remainder */
- skb_pull(pkt, BRCMF_FIRSTREAD);
- pkt_align(pkt, rdlen, BRCMF_SDALIGN);
-
- /* Read the remaining frame data */
- sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
- SDIO_FUNC_2, F2SYNC, ((u8 *) (pkt->data)),
- rdlen, pkt);
- bus->f2rxdata++;
-
- if (sdret < 0) {
- brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen,
- ((chan == SDPCM_EVENT_CHANNEL) ? "event"
- : ((chan == SDPCM_DATA_CHANNEL) ? "data"
- : "test")), sdret);
- brcmu_pkt_buf_free_skb(pkt);
- bus->drvr->rx_errors++;
- brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan));
- continue;
- }
-
- /* Copy the already-read portion */
- skb_push(pkt, BRCMF_FIRSTREAD);
- memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD);
-
-#ifdef BCMDBG
- if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
- printk(KERN_DEBUG "Rx Data:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- pkt->data, len);
- }
-#endif
-
-deliver:
- /* Save superframe descriptor and allocate packet frame */
- if (chan == SDPCM_GLOM_CHANNEL) {
- if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
- brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
- len);
-#ifdef BCMDBG
- if (BRCMF_GLOM_ON()) {
- printk(KERN_DEBUG "Glom Data:\n");
- print_hex_dump_bytes("",
- DUMP_PREFIX_OFFSET,
- pkt->data, len);
- }
-#endif
- __skb_trim(pkt, len);
- skb_pull(pkt, SDPCM_HDRLEN);
- bus->glomd = pkt;
- } else {
- brcmf_dbg(ERROR, "%s: glom superframe w/o "
- "descriptor!\n", __func__);
- brcmf_sdbrcm_rxfail(bus, false, false);
- }
- continue;
- }
-
- /* Fill in packet len and prio, deliver upward */
- __skb_trim(pkt, len);
- skb_pull(pkt, doff);
-
- if (pkt->len == 0) {
- brcmu_pkt_buf_free_skb(pkt);
- continue;
- } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pkt) != 0) {
- brcmf_dbg(ERROR, "rx protocol error\n");
- brcmu_pkt_buf_free_skb(pkt);
- bus->drvr->rx_errors++;
- continue;
- }
-
- /* Unlock during rx call */
- up(&bus->sdsem);
- brcmf_rx_frame(bus->drvr, ifidx, pkt, 1);
- down(&bus->sdsem);
- }
- rxcount = maxframes - rxleft;
-#ifdef BCMDBG
- /* Message if we hit the limit */
- if (!rxleft)
- brcmf_dbg(DATA, "hit rx limit of %d frames\n",
- maxframes);
- else
-#endif /* BCMDBG */
- brcmf_dbg(DATA, "processed %d frames\n", rxcount);
- /* Back off rxseq if awaiting rtx, update rx_seq */
- if (bus->rxskip)
- rxseq--;
- bus->rx_seq = rxseq;
-
- return rxcount;
-}
-
-static int
-brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, u32 addr, uint fn, uint flags,
- u8 *buf, uint nbytes, struct sk_buff *pkt)
-{
- return brcmf_sdcard_send_buf
- (bus->sdiodev, addr, fn, flags, buf, nbytes, pkt);
-}
-
-static void
-brcmf_sdbrcm_wait_for_event(struct brcmf_bus *bus, bool *lockvar)
-{
- up(&bus->sdsem);
- wait_event_interruptible_timeout(bus->ctrl_wait,
- (*lockvar == false), HZ * 2);
- down(&bus->sdsem);
- return;
-}
-
-static void
-brcmf_sdbrcm_wait_event_wakeup(struct brcmf_bus *bus)
-{
- if (waitqueue_active(&bus->ctrl_wait))
- wake_up_interruptible(&bus->ctrl_wait);
- return;
-}
-
-/* Writes a HW/SW header into the packet and sends it. */
-/* Assumes: (a) header space already there, (b) caller holds lock */
-static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt,
- uint chan, bool free_pkt)
-{
- int ret;
- u8 *frame;
- u16 len, pad = 0;
- u32 swheader;
- struct sk_buff *new;
- int i;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- frame = (u8 *) (pkt->data);
-
- /* Add alignment padding, allocate new packet if needed */
- pad = ((unsigned long)frame % BRCMF_SDALIGN);
- if (pad) {
- if (skb_headroom(pkt) < pad) {
- brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n",
- skb_headroom(pkt), pad);
- bus->drvr->tx_realloc++;
- new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN);
- if (!new) {
- brcmf_dbg(ERROR, "couldn't allocate new %d-byte packet\n",
- pkt->len + BRCMF_SDALIGN);
- ret = -ENOMEM;
- goto done;
- }
-
- pkt_align(new, pkt->len, BRCMF_SDALIGN);
- memcpy(new->data, pkt->data, pkt->len);
- if (free_pkt)
- brcmu_pkt_buf_free_skb(pkt);
- /* free the pkt if canned one is not used */
- free_pkt = true;
- pkt = new;
- frame = (u8 *) (pkt->data);
- /* precondition: (frame % BRCMF_SDALIGN) == 0) */
- pad = 0;
- } else {
- skb_push(pkt, pad);
- frame = (u8 *) (pkt->data);
- /* precondition: pad + SDPCM_HDRLEN <= pkt->len */
- memset(frame, 0, pad + SDPCM_HDRLEN);
- }
- }
- /* precondition: pad < BRCMF_SDALIGN */
-
- /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
- len = (u16) (pkt->len);
- *(__le16 *) frame = cpu_to_le16(len);
- *(((__le16 *) frame) + 1) = cpu_to_le16(~len);
-
- /* Software tag: channel, sequence number, data offset */
- swheader =
- ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
- (((pad +
- SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
-
- put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
- put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
-
-#ifdef BCMDBG
- tx_packets[pkt->priority]++;
- if (BRCMF_BYTES_ON() &&
- (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
- (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
- printk(KERN_DEBUG "Tx Frame:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len);
- } else if (BRCMF_HDRS_ON()) {
- printk(KERN_DEBUG "TxHdr:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- frame, min_t(u16, len, 16));
- }
-#endif
-
- /* Raise len to next SDIO block to eliminate tail command */
- if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
- u16 pad = bus->blocksize - (len % bus->blocksize);
- if ((pad <= bus->roundup) && (pad < bus->blocksize))
- len += pad;
- } else if (len % BRCMF_SDALIGN) {
- len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
- }
-
- /* Some controllers have trouble with odd bytes -- round to even */
- if (len & (ALIGNMENT - 1))
- len = roundup(len, ALIGNMENT);
-
- ret = brcmf_sdbrcm_send_buf(bus, bus->sdiodev->sbwad,
- SDIO_FUNC_2, F2SYNC, frame,
- len, pkt);
- bus->f2txdata++;
-
- if (ret < 0) {
- /* On failure, abort the command and terminate the frame */
- brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
- ret);
- bus->tx_sderrs++;
-
- brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
- NULL);
- bus->f1regdata++;
-
- for (i = 0; i < 3; i++) {
- u8 hi, lo;
- hi = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_1,
- SBSDIO_FUNC1_WFRAMEBCHI,
- NULL);
- lo = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_1,
- SBSDIO_FUNC1_WFRAMEBCLO,
- NULL);
- bus->f1regdata += 2;
- if ((hi == 0) && (lo == 0))
- break;
- }
-
- }
- if (ret == 0)
- bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
-
-done:
- /* restore pkt buffer pointer before calling tx complete routine */
- skb_pull(pkt, SDPCM_HDRLEN + pad);
- up(&bus->sdsem);
- brcmf_txcomplete(bus->drvr, pkt, ret != 0);
- down(&bus->sdsem);
-
- if (free_pkt)
- brcmu_pkt_buf_free_skb(pkt);
-
- return ret;
-}
-
-static uint brcmf_sdbrcm_sendfromq(struct brcmf_bus *bus, uint maxframes)
-{
- struct sk_buff *pkt;
- u32 intstatus = 0;
- uint retries = 0;
- int ret = 0, prec_out;
- uint cnt = 0;
- uint datalen;
- u8 tx_prec_map;
-
- struct brcmf_pub *drvr = bus->drvr;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- tx_prec_map = ~bus->flowcontrol;
-
- /* Send frames until the limit or some other event */
- for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) {
- spin_lock_bh(&bus->txqlock);
- pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
- if (pkt == NULL) {
- spin_unlock_bh(&bus->txqlock);
- break;
- }
- spin_unlock_bh(&bus->txqlock);
- datalen = pkt->len - SDPCM_HDRLEN;
-
- ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
- if (ret)
- bus->drvr->tx_errors++;
- else
- bus->drvr->dstats.tx_bytes += datalen;
-
- /* In poll mode, need to check for other events */
- if (!bus->intr && cnt) {
- /* Check device status, signal pending interrupt */
- r_sdreg32(bus, &intstatus,
- offsetof(struct sdpcmd_regs, intstatus),
- &retries);
- bus->f2txdata++;
- if (brcmf_sdcard_regfail(bus->sdiodev))
- break;
- if (intstatus & bus->hostintmask)
- bus->ipend = true;
- }
- }
-
- /* Deflow-control stack if needed */
- if (drvr->up && (drvr->busstate == BRCMF_BUS_DATA) &&
- drvr->txoff && (pktq_len(&bus->txq) < TXLOW))
- brcmf_txflowcontrol(drvr, 0, OFF);
-
- return cnt;
-}
-
-static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus)
-{
- u32 intstatus, newstatus = 0;
- uint retries = 0;
- uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
- uint txlimit = bus->txbound; /* Tx frames to send before resched */
- uint framecnt = 0; /* Temporary counter of tx/rx frames */
- bool rxdone = true; /* Flag for no more read data */
- bool resched = false; /* Flag indicating resched wanted */
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Start with leftover status bits */
- intstatus = bus->intstatus;
-
- down(&bus->sdsem);
-
- /* If waiting for HTAVAIL, check status */
- if (bus->clkstate == CLK_PENDING) {
- int err;
- u8 clkctl, devctl = 0;
-
-#ifdef BCMDBG
- /* Check for inconsistent device control */
- devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, &err);
- if (err) {
- brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
- bus->drvr->busstate = BRCMF_BUS_DOWN;
- }
-#endif /* BCMDBG */
-
- /* Read CSR, if clock on switch to AVAIL, else ignore */
- clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, &err);
- if (err) {
- brcmf_dbg(ERROR, "error reading CSR: %d\n",
- err);
- bus->drvr->busstate = BRCMF_BUS_DOWN;
- }
-
- brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
- devctl, clkctl);
-
- if (SBSDIO_HTAV(clkctl)) {
- devctl = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, &err);
- if (err) {
- brcmf_dbg(ERROR, "error reading DEVCTL: %d\n",
- err);
- bus->drvr->busstate = BRCMF_BUS_DOWN;
- }
- devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_DEVICE_CTL, devctl, &err);
- if (err) {
- brcmf_dbg(ERROR, "error writing DEVCTL: %d\n",
- err);
- bus->drvr->busstate = BRCMF_BUS_DOWN;
- }
- bus->clkstate = CLK_AVAIL;
- } else {
- goto clkwait;
- }
- }
-
- bus_wake(bus);
-
- /* Make sure backplane clock is on */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true);
- if (bus->clkstate == CLK_PENDING)
- goto clkwait;
-
- /* Pending interrupt indicates new device status */
- if (bus->ipend) {
- bus->ipend = false;
- r_sdreg32(bus, &newstatus,
- offsetof(struct sdpcmd_regs, intstatus), &retries);
- bus->f1regdata++;
- if (brcmf_sdcard_regfail(bus->sdiodev))
- newstatus = 0;
- newstatus &= bus->hostintmask;
- bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
- if (newstatus) {
- w_sdreg32(bus, newstatus,
- offsetof(struct sdpcmd_regs, intstatus),
- &retries);
- bus->f1regdata++;
- }
- }
-
- /* Merge new bits with previous */
- intstatus |= newstatus;
- bus->intstatus = 0;
-
- /* Handle flow-control change: read new state in case our ack
- * crossed another change interrupt. If change still set, assume
- * FC ON for safety, let next loop through do the debounce.
- */
- if (intstatus & I_HMB_FC_CHANGE) {
- intstatus &= ~I_HMB_FC_CHANGE;
- w_sdreg32(bus, I_HMB_FC_CHANGE,
- offsetof(struct sdpcmd_regs, intstatus), &retries);
-
- r_sdreg32(bus, &newstatus,
- offsetof(struct sdpcmd_regs, intstatus), &retries);
- bus->f1regdata += 2;
- bus->fcstate =
- !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
- intstatus |= (newstatus & bus->hostintmask);
- }
-
- /* Handle host mailbox indication */
- if (intstatus & I_HMB_HOST_INT) {
- intstatus &= ~I_HMB_HOST_INT;
- intstatus |= brcmf_sdbrcm_hostmail(bus);
- }
-
- /* Generally don't ask for these, can get CRC errors... */
- if (intstatus & I_WR_OOSYNC) {
- brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n");
- intstatus &= ~I_WR_OOSYNC;
- }
-
- if (intstatus & I_RD_OOSYNC) {
- brcmf_dbg(ERROR, "Dongle reports RD_OOSYNC\n");
- intstatus &= ~I_RD_OOSYNC;
- }
-
- if (intstatus & I_SBINT) {
- brcmf_dbg(ERROR, "Dongle reports SBINT\n");
- intstatus &= ~I_SBINT;
- }
-
- /* Would be active due to wake-wlan in gSPI */
- if (intstatus & I_CHIPACTIVE) {
- brcmf_dbg(INFO, "Dongle reports CHIPACTIVE\n");
- intstatus &= ~I_CHIPACTIVE;
- }
-
- /* Ignore frame indications if rxskip is set */
- if (bus->rxskip)
- intstatus &= ~I_HMB_FRAME_IND;
-
- /* On frame indication, read available frames */
- if (PKT_AVAILABLE()) {
- framecnt = brcmf_sdbrcm_readframes(bus, rxlimit, &rxdone);
- if (rxdone || bus->rxskip)
- intstatus &= ~I_HMB_FRAME_IND;
- rxlimit -= min(framecnt, rxlimit);
- }
-
- /* Keep still-pending events for next scheduling */
- bus->intstatus = intstatus;
-
-clkwait:
- if (data_ok(bus) && bus->ctrl_frame_stat &&
- (bus->clkstate == CLK_AVAIL)) {
- int ret, i;
-
- ret = brcmf_sdbrcm_send_buf(bus, bus->sdiodev->sbwad,
- SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf,
- (u32) bus->ctrl_frame_len, NULL);
-
- if (ret < 0) {
- /* On failure, abort the command and
- terminate the frame */
- brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
- ret);
- bus->tx_sderrs++;
-
- brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
- NULL);
- bus->f1regdata++;
-
- for (i = 0; i < 3; i++) {
- u8 hi, lo;
- hi = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_1,
- SBSDIO_FUNC1_WFRAMEBCHI,
- NULL);
- lo = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_1,
- SBSDIO_FUNC1_WFRAMEBCLO,
- NULL);
- bus->f1regdata += 2;
- if ((hi == 0) && (lo == 0))
- break;
- }
-
- }
- if (ret == 0)
- bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
-
- brcmf_dbg(INFO, "Return_dpc value is : %d\n", ret);
- bus->ctrl_frame_stat = false;
- brcmf_sdbrcm_wait_event_wakeup(bus);
- }
- /* Send queued frames (limit 1 if rx may still be pending) */
- else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
- brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
- && data_ok(bus)) {
- framecnt = rxdone ? txlimit : min(txlimit, bus->txminmax);
- framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt);
- txlimit -= framecnt;
- }
-
- /* Resched if events or tx frames are pending,
- else await next interrupt */
- /* On failed register access, all bets are off:
- no resched or interrupts */
- if ((bus->drvr->busstate == BRCMF_BUS_DOWN) ||
- brcmf_sdcard_regfail(bus->sdiodev)) {
- brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation %d\n",
- brcmf_sdcard_regfail(bus->sdiodev));
- bus->drvr->busstate = BRCMF_BUS_DOWN;
- bus->intstatus = 0;
- } else if (bus->clkstate == CLK_PENDING) {
- brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n");
- resched = true;
- } else if (bus->intstatus || bus->ipend ||
- (!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)
- && data_ok(bus)) || PKT_AVAILABLE()) {
- resched = true;
- }
-
- bus->dpc_sched = resched;
-
- /* If we're done for now, turn off clock request. */
- if ((bus->clkstate != CLK_PENDING)
- && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
- bus->activity = false;
- brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
- }
-
- up(&bus->sdsem);
-
- return resched;
-}
-
-static int brcmf_sdbrcm_dpc_thread(void *data)
-{
- struct brcmf_bus *bus = (struct brcmf_bus *) data;
-
- allow_signal(SIGTERM);
- /* Run until signal received */
- while (1) {
- if (kthread_should_stop())
- break;
- if (!wait_for_completion_interruptible(&bus->dpc_wait)) {
- /* Call bus dpc unless it indicated down
- (then clean stop) */
- if (bus->drvr->busstate != BRCMF_BUS_DOWN) {
- if (brcmf_sdbrcm_dpc(bus))
- complete(&bus->dpc_wait);
- } else {
- /* after stopping the bus, exit thread */
- brcmf_sdbrcm_bus_stop(bus);
- bus->dpc_tsk = NULL;
- break;
- }
- } else
- break;
- }
- return 0;
-}
-
-int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *pkt)
-{
- int ret = -EBADE;
- uint datalen, prec;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- datalen = pkt->len;
-
- /* Add space for the header */
- skb_push(pkt, SDPCM_HDRLEN);
- /* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */
-
- prec = prio2prec((pkt->priority & PRIOMASK));
-
- /* Check for existing queue, current flow-control,
- pending event, or pending clock */
- brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq));
- bus->fcqueued++;
-
- /* Priority based enq */
- spin_lock_bh(&bus->txqlock);
- if (brcmf_c_prec_enq(bus->drvr, &bus->txq, pkt, prec) == false) {
- skb_pull(pkt, SDPCM_HDRLEN);
- brcmf_txcomplete(bus->drvr, pkt, false);
- brcmu_pkt_buf_free_skb(pkt);
- brcmf_dbg(ERROR, "out of bus->txq !!!\n");
- ret = -ENOSR;
- } else {
- ret = 0;
- }
- spin_unlock_bh(&bus->txqlock);
-
- if (pktq_len(&bus->txq) >= TXHI)
- brcmf_txflowcontrol(bus->drvr, 0, ON);
-
-#ifdef BCMDBG
- if (pktq_plen(&bus->txq, prec) > qcount[prec])
- qcount[prec] = pktq_plen(&bus->txq, prec);
-#endif
- /* Schedule DPC if needed to send queued packet(s) */
- if (!bus->dpc_sched) {
- bus->dpc_sched = true;
- if (bus->dpc_tsk)
- complete(&bus->dpc_wait);
- }
-
- return ret;
-}
-
-static int
-brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data,
- uint size)
-{
- int bcmerror = 0;
- u32 sdaddr;
- uint dsize;
-
- /* Determine initial transfer parameters */
- sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
- if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
- dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
- else
- dsize = size;
-
- /* Set the backplane window to include the start address */
- bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address);
- if (bcmerror) {
- brcmf_dbg(ERROR, "window change failed\n");
- goto xfer_done;
- }
-
- /* Do the transfer(s) */
- while (size) {
- brcmf_dbg(INFO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
- write ? "write" : "read", dsize,
- sdaddr, address & SBSDIO_SBWINDOW_MASK);
- bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write,
- sdaddr, data, dsize);
- if (bcmerror) {
- brcmf_dbg(ERROR, "membytes transfer failed\n");
- break;
- }
-
- /* Adjust for next transfer (if any) */
- size -= dsize;
- if (size) {
- data += dsize;
- address += dsize;
- bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev,
- address);
- if (bcmerror) {
- brcmf_dbg(ERROR, "window change failed\n");
- break;
- }
- sdaddr = 0;
- dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
- }
- }
-
-xfer_done:
- /* Return the window to backplane enumeration space for core access */
- if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad))
- brcmf_dbg(ERROR, "FAILED to set window back to 0x%x\n",
- bus->sdiodev->sbwad);
-
- return bcmerror;
-}
-
-#ifdef BCMDBG
-#define CONSOLE_LINE_MAX 192
-
-static int brcmf_sdbrcm_readconsole(struct brcmf_bus *bus)
-{
- struct brcmf_console *c = &bus->console;
- u8 line[CONSOLE_LINE_MAX], ch;
- u32 n, idx, addr;
- int rv;
-
- /* Don't do anything until FWREADY updates console address */
- if (bus->console_addr == 0)
- return 0;
-
- /* Read console log struct */
- addr = bus->console_addr + offsetof(struct rte_console, log_le);
- rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le,
- sizeof(c->log_le));
- if (rv < 0)
- return rv;
-
- /* Allocate console buffer (one time only) */
- if (c->buf == NULL) {
- c->bufsize = le32_to_cpu(c->log_le.buf_size);
- c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
- if (c->buf == NULL)
- return -ENOMEM;
- }
-
- idx = le32_to_cpu(c->log_le.idx);
-
- /* Protect against corrupt value */
- if (idx > c->bufsize)
- return -EBADE;
-
- /* Skip reading the console buffer if the index pointer
- has not moved */
- if (idx == c->last)
- return 0;
-
- /* Read the console buffer */
- addr = le32_to_cpu(c->log_le.buf);
- rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize);
- if (rv < 0)
- return rv;
-
- while (c->last != idx) {
- for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
- if (c->last == idx) {
- /* This would output a partial line.
- * Instead, back up
- * the buffer pointer and output this
- * line next time around.
- */
- if (c->last >= n)
- c->last -= n;
- else
- c->last = c->bufsize - n;
- goto break2;
- }
- ch = c->buf[c->last];
- c->last = (c->last + 1) % c->bufsize;
- if (ch == '\n')
- break;
- line[n] = ch;
- }
-
- if (n > 0) {
- if (line[n - 1] == '\r')
- n--;
- line[n] = 0;
- printk(KERN_DEBUG "CONSOLE: %s\n", line);
- }
- }
-break2:
-
- return 0;
-}
-#endif /* BCMDBG */
-
-static int brcmf_tx_frame(struct brcmf_bus *bus, u8 *frame, u16 len)
-{
- int i;
- int ret;
-
- bus->ctrl_frame_stat = false;
- ret = brcmf_sdbrcm_send_buf(bus, bus->sdiodev->sbwad,
- SDIO_FUNC_2, F2SYNC, frame, len, NULL);
-
- if (ret < 0) {
- /* On failure, abort the command and terminate the frame */
- brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
- ret);
- bus->tx_sderrs++;
-
- brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_FRAMECTRL,
- SFC_WF_TERM, NULL);
- bus->f1regdata++;
-
- for (i = 0; i < 3; i++) {
- u8 hi, lo;
- hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_WFRAMEBCHI,
- NULL);
- lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_WFRAMEBCLO,
- NULL);
- bus->f1regdata += 2;
- if (hi == 0 && lo == 0)
- break;
- }
- return ret;
- }
-
- bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
-
- return ret;
-}
-
-int
-brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen)
-{
- u8 *frame;
- u16 len;
- u32 swheader;
- uint retries = 0;
- u8 doff = 0;
- int ret = -1;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Back the pointer to make a room for bus header */
- frame = msg - SDPCM_HDRLEN;
- len = (msglen += SDPCM_HDRLEN);
-
- /* Add alignment padding (optional for ctl frames) */
- doff = ((unsigned long)frame % BRCMF_SDALIGN);
- if (doff) {
- frame -= doff;
- len += doff;
- msglen += doff;
- memset(frame, 0, doff + SDPCM_HDRLEN);
- }
- /* precondition: doff < BRCMF_SDALIGN */
- doff += SDPCM_HDRLEN;
-
- /* Round send length to next SDIO block */
- if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
- u16 pad = bus->blocksize - (len % bus->blocksize);
- if ((pad <= bus->roundup) && (pad < bus->blocksize))
- len += pad;
- } else if (len % BRCMF_SDALIGN) {
- len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
- }
-
- /* Satisfy length-alignment requirements */
- if (len & (ALIGNMENT - 1))
- len = roundup(len, ALIGNMENT);
-
- /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
-
- /* Need to lock here to protect txseq and SDIO tx calls */
- down(&bus->sdsem);
-
- bus_wake(bus);
-
- /* Make sure backplane clock is on */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
-
- /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
- *(__le16 *) frame = cpu_to_le16((u16) msglen);
- *(((__le16 *) frame) + 1) = cpu_to_le16(~msglen);
-
- /* Software tag: channel, sequence number, data offset */
- swheader =
- ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
- SDPCM_CHANNEL_MASK)
- | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
- SDPCM_DOFFSET_MASK);
- put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
- put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
-
- if (!data_ok(bus)) {
- brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
- bus->tx_max, bus->tx_seq);
- bus->ctrl_frame_stat = true;
- /* Send from dpc */
- bus->ctrl_frame_buf = frame;
- bus->ctrl_frame_len = len;
-
- brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat);
-
- if (bus->ctrl_frame_stat == false) {
- brcmf_dbg(INFO, "ctrl_frame_stat == false\n");
- ret = 0;
- } else {
- brcmf_dbg(INFO, "ctrl_frame_stat == true\n");
- ret = -1;
- }
- }
-
- if (ret == -1) {
-#ifdef BCMDBG
- if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
- printk(KERN_DEBUG "Tx Frame:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- frame, len);
- } else if (BRCMF_HDRS_ON()) {
- printk(KERN_DEBUG "TxHdr:\n");
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
- frame, min_t(u16, len, 16));
- }
-#endif
-
- do {
- ret = brcmf_tx_frame(bus, frame, len);
- } while (ret < 0 && retries++ < TXRETRIES);
- }
-
- if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
- bus->activity = false;
- brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
- }
-
- up(&bus->sdsem);
-
- if (ret)
- bus->drvr->tx_ctlerrs++;
- else
- bus->drvr->tx_ctlpkts++;
-
- return ret ? -EIO : 0;
-}
-
-int
-brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen)
-{
- int timeleft;
- uint rxlen = 0;
- bool pending;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Wait until control frame is available */
- timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending);
-
- down(&bus->sdsem);
- rxlen = bus->rxlen;
- memcpy(msg, bus->rxctl, min(msglen, rxlen));
- bus->rxlen = 0;
- up(&bus->sdsem);
-
- if (rxlen) {
- brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n",
- rxlen, msglen);
- } else if (timeleft == 0) {
- brcmf_dbg(ERROR, "resumed on timeout\n");
- } else if (pending == true) {
- brcmf_dbg(CTL, "cancelled\n");
- return -ERESTARTSYS;
- } else {
- brcmf_dbg(CTL, "resumed for unknown reason?\n");
- }
-
- if (rxlen)
- bus->drvr->rx_ctlpkts++;
- else
- bus->drvr->rx_ctlerrs++;
-
- return rxlen ? (int)rxlen : -ETIMEDOUT;
-}
-
-static int brcmf_sdbrcm_downloadvars(struct brcmf_bus *bus, void *arg, int len)
-{
- int bcmerror = 0;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Basic sanity checks */
- if (bus->drvr->up) {
- bcmerror = -EISCONN;
- goto err;
- }
- if (!len) {
- bcmerror = -EOVERFLOW;
- goto err;
- }
-
- /* Free the old ones and replace with passed variables */
- kfree(bus->vars);
-
- bus->vars = kmalloc(len, GFP_ATOMIC);
- bus->varsz = bus->vars ? len : 0;
- if (bus->vars == NULL) {
- bcmerror = -ENOMEM;
- goto err;
- }
-
- /* Copy the passed variables, which should include the
- terminating double-null */
- memcpy(bus->vars, arg, bus->varsz);
-err:
- return bcmerror;
-}
-
-static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus)
-{
- int bcmerror = 0;
- u32 varsize;
- u32 varaddr;
- u8 *vbuffer;
- u32 varsizew;
- __le32 varsizew_le;
-#ifdef BCMDBG
- char *nvram_ularray;
-#endif /* BCMDBG */
-
- /* Even if there are no vars are to be written, we still
- need to set the ramsize. */
- varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
- varaddr = (bus->ramsize - 4) - varsize;
-
- if (bus->vars) {
- vbuffer = kzalloc(varsize, GFP_ATOMIC);
- if (!vbuffer)
- return -ENOMEM;
-
- memcpy(vbuffer, bus->vars, bus->varsz);
-
- /* Write the vars list */
- bcmerror =
- brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
-#ifdef BCMDBG
- /* Verify NVRAM bytes */
- brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
- nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
- if (!nvram_ularray)
- return -ENOMEM;
-
- /* Upload image to verify downloaded contents. */
- memset(nvram_ularray, 0xaa, varsize);
-
- /* Read the vars list to temp buffer for comparison */
- bcmerror =
- brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
- varsize);
- if (bcmerror) {
- brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
- bcmerror, varsize, varaddr);
- }
- /* Compare the org NVRAM with the one read from RAM */
- if (memcmp(vbuffer, nvram_ularray, varsize))
- brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
- else
- brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
-
- kfree(nvram_ularray);
-#endif /* BCMDBG */
-
- kfree(vbuffer);
- }
-
- /* adjust to the user specified RAM */
- brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
- brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
- varaddr, varsize);
- varsize = ((bus->ramsize - 4) - varaddr);
-
- /*
- * Determine the length token:
- * Varsize, converted to words, in lower 16-bits, checksum
- * in upper 16-bits.
- */
- if (bcmerror) {
- varsizew = 0;
- varsizew_le = cpu_to_le32(0);
- } else {
- varsizew = varsize / 4;
- varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
- varsizew_le = cpu_to_le32(varsizew);
- }
-
- brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
- varsize, varsizew);
-
- /* Write the length token to the last word */
- bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
- (u8 *)&varsizew_le, 4);
-
- return bcmerror;
-}
-
-static void
-brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_dev *sdiodev, u32 corebase)
-{
- u32 regdata;
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbtmstatelow), 4);
- if (regdata & SBTML_RESET)
- return;
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbtmstatelow), 4);
- if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) {
- /*
- * set target reject and spin until busy is clear
- * (preserve core-specific bits)
- */
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbtmstatelow), 4);
- brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow),
- 4, regdata | SBTML_REJ);
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbtmstatelow), 4);
- udelay(1);
- SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbtmstatehigh), 4) &
- SBTMH_BUSY), 100000);
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbtmstatehigh), 4);
- if (regdata & SBTMH_BUSY)
- brcmf_dbg(ERROR, "ARM core still busy\n");
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbidlow), 4);
- if (regdata & SBIDL_INIT) {
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbimstate), 4) |
- SBIM_RJ;
- brcmf_sdcard_reg_write(sdiodev,
- CORE_SB(corebase, sbimstate), 4,
- regdata);
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbimstate), 4);
- udelay(1);
- SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbimstate), 4) &
- SBIM_BY), 100000);
- }
-
- /* set reset and reject while enabling the clocks */
- brcmf_sdcard_reg_write(sdiodev,
- CORE_SB(corebase, sbtmstatelow), 4,
- (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
- SBTML_REJ | SBTML_RESET));
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbtmstatelow), 4);
- udelay(10);
-
- /* clear the initiator reject bit */
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbidlow), 4);
- if (regdata & SBIDL_INIT) {
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbimstate), 4) &
- ~SBIM_RJ;
- brcmf_sdcard_reg_write(sdiodev,
- CORE_SB(corebase, sbimstate), 4,
- regdata);
- }
- }
-
- /* leave reset and reject asserted */
- brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
- (SBTML_REJ | SBTML_RESET));
- udelay(1);
-}
-
-static void
-brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase)
-{
- u32 regdata;
-
- /*
- * Must do the disable sequence first to work for
- * arbitrary current core state.
- */
- brcmf_sdbrcm_chip_disablecore(sdiodev, corebase);
-
- /*
- * Now do the initialization sequence.
- * set reset while enabling the clock and
- * forcing them on throughout the core
- */
- brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
- ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
- SBTML_RESET);
- udelay(1);
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbtmstatehigh), 4);
- if (regdata & SBTMH_SERR)
- brcmf_sdcard_reg_write(sdiodev,
- CORE_SB(corebase, sbtmstatehigh), 4, 0);
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(corebase, sbimstate), 4);
- if (regdata & (SBIM_IBE | SBIM_TO))
- brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4,
- regdata & ~(SBIM_IBE | SBIM_TO));
-
- /* clear reset and allow it to propagate throughout the core */
- brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
- (SICF_FGC << SBTML_SICF_SHIFT) |
- (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
- udelay(1);
-
- /* leave clock enabled */
- brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
- (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
- udelay(1);
-}
-
-static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter)
-{
- uint retries;
- u32 regdata;
- int bcmerror = 0;
-
- /* To enter download state, disable ARM and reset SOCRAM.
- * To exit download state, simply reset ARM (default is RAM boot).
- */
- if (enter) {
- bus->alp_only = true;
-
- brcmf_sdbrcm_chip_disablecore(bus->sdiodev,
- bus->ci->armcorebase);
-
- brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->ramcorebase);
-
- /* Clear the top bit of memory */
- if (bus->ramsize) {
- u32 zeros = 0;
- brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4,
- (u8 *)&zeros, 4);
- }
- } else {
- regdata = brcmf_sdcard_reg_read(bus->sdiodev,
- CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4);
- regdata &= (SBTML_RESET | SBTML_REJ_MASK |
- (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
- if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) {
- brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n");
- bcmerror = -EBADE;
- goto fail;
- }
-
- bcmerror = brcmf_sdbrcm_write_vars(bus);
- if (bcmerror) {
- brcmf_dbg(ERROR, "no vars written to RAM\n");
- bcmerror = 0;
- }
-
- w_sdreg32(bus, 0xFFFFFFFF,
- offsetof(struct sdpcmd_regs, intstatus), &retries);
-
- brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->armcorebase);
-
- /* Allow HT Clock now that the ARM is running. */
- bus->alp_only = false;
-
- bus->drvr->busstate = BRCMF_BUS_LOAD;
- }
-fail:
- return bcmerror;
-}
-
-static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus)
-{
- if (bus->firmware->size < bus->fw_ptr + len)
- len = bus->firmware->size - bus->fw_ptr;
-
- memcpy(buf, &bus->firmware->data[bus->fw_ptr], len);
- bus->fw_ptr += len;
- return len;
-}
-
-MODULE_FIRMWARE(BCM4329_FW_NAME);
-MODULE_FIRMWARE(BCM4329_NV_NAME);
-
-static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus)
-{
- int offset = 0;
- uint len;
- u8 *memblock = NULL, *memptr;
- int ret;
-
- brcmf_dbg(INFO, "Enter\n");
-
- bus->fw_name = BCM4329_FW_NAME;
- ret = request_firmware(&bus->firmware, bus->fw_name,
- &bus->sdiodev->func[2]->dev);
- if (ret) {
- brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret);
- return ret;
- }
- bus->fw_ptr = 0;
-
- memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC);
- if (memblock == NULL) {
- ret = -ENOMEM;
- goto err;
- }
- if ((u32)(unsigned long)memblock % BRCMF_SDALIGN)
- memptr += (BRCMF_SDALIGN -
- ((u32)(unsigned long)memblock % BRCMF_SDALIGN));
-
- /* Download image */
- while ((len =
- brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) {
- ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len);
- if (ret) {
- brcmf_dbg(ERROR, "error %d on writing %d membytes at 0x%08x\n",
- ret, MEMBLOCK, offset);
- goto err;
- }
-
- offset += MEMBLOCK;
- }
-
-err:
- kfree(memblock);
-
- release_firmware(bus->firmware);
- bus->fw_ptr = 0;
-
- return ret;
-}
-
-/*
- * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
- * and ending in a NUL.
- * Removes carriage returns, empty lines, comment lines, and converts
- * newlines to NULs.
- * Shortens buffer as needed and pads with NULs. End of buffer is marked
- * by two NULs.
-*/
-
-static uint brcmf_process_nvram_vars(char *varbuf, uint len)
-{
- char *dp;
- bool findNewline;
- int column;
- uint buf_len, n;
-
- dp = varbuf;
-
- findNewline = false;
- column = 0;
-
- for (n = 0; n < len; n++) {
- if (varbuf[n] == 0)
- break;
- if (varbuf[n] == '\r')
- continue;
- if (findNewline && varbuf[n] != '\n')
- continue;
- findNewline = false;
- if (varbuf[n] == '#') {
- findNewline = true;
- continue;
- }
- if (varbuf[n] == '\n') {
- if (column == 0)
- continue;
- *dp++ = 0;
- column = 0;
- continue;
- }
- *dp++ = varbuf[n];
- column++;
- }
- buf_len = dp - varbuf;
-
- while (dp < varbuf + n)
- *dp++ = 0;
-
- return buf_len;
-}
-
-static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus)
-{
- uint len;
- char *memblock = NULL;
- char *bufp;
- int ret;
-
- bus->nv_name = BCM4329_NV_NAME;
- ret = request_firmware(&bus->firmware, bus->nv_name,
- &bus->sdiodev->func[2]->dev);
- if (ret) {
- brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
- return ret;
- }
- bus->fw_ptr = 0;
-
- memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
- if (memblock == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);
-
- if (len > 0 && len < MEMBLOCK) {
- bufp = (char *)memblock;
- bufp[len] = 0;
- len = brcmf_process_nvram_vars(bufp, len);
- bufp += len;
- *bufp++ = 0;
- if (len)
- ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
- if (ret)
- brcmf_dbg(ERROR, "error downloading vars: %d\n", ret);
- } else {
- brcmf_dbg(ERROR, "error reading nvram file: %d\n", len);
- ret = -EIO;
- }
-
-err:
- kfree(memblock);
-
- release_firmware(bus->firmware);
- bus->fw_ptr = 0;
-
- return ret;
-}
-
-static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus)
-{
- int bcmerror = -1;
-
- /* Keep arm in reset */
- if (brcmf_sdbrcm_download_state(bus, true)) {
- brcmf_dbg(ERROR, "error placing ARM core in reset\n");
- goto err;
- }
-
- /* External image takes precedence if specified */
- if (brcmf_sdbrcm_download_code_file(bus)) {
- brcmf_dbg(ERROR, "dongle image file download failed\n");
- goto err;
- }
-
- /* External nvram takes precedence if specified */
- if (brcmf_sdbrcm_download_nvram(bus))
- brcmf_dbg(ERROR, "dongle nvram file download failed\n");
-
- /* Take arm out of reset */
- if (brcmf_sdbrcm_download_state(bus, false)) {
- brcmf_dbg(ERROR, "error getting out of ARM core reset\n");
- goto err;
- }
-
- bcmerror = 0;
-
-err:
- return bcmerror;
-}
-
-static bool
-brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus)
-{
- bool ret;
-
- /* Download the firmware */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
-
- ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
-
- brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
-
- return ret;
-}
-
-void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus)
-{
- u32 local_hostintmask;
- u8 saveclk;
- uint retries;
- int err;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (bus->watchdog_tsk) {
- send_sig(SIGTERM, bus->watchdog_tsk, 1);
- kthread_stop(bus->watchdog_tsk);
- bus->watchdog_tsk = NULL;
- }
-
- if (bus->dpc_tsk && bus->dpc_tsk != current) {
- send_sig(SIGTERM, bus->dpc_tsk, 1);
- kthread_stop(bus->dpc_tsk);
- bus->dpc_tsk = NULL;
- }
-
- down(&bus->sdsem);
-
- bus_wake(bus);
-
- /* Enable clock for device interrupts */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
-
- /* Disable and clear interrupts at the chip level also */
- w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries);
- local_hostintmask = bus->hostintmask;
- bus->hostintmask = 0;
-
- /* Change our idea of bus state */
- bus->drvr->busstate = BRCMF_BUS_DOWN;
-
- /* Force clocks on backplane to be sure F2 interrupt propagates */
- saveclk = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, &err);
- if (!err) {
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR,
- (saveclk | SBSDIO_FORCE_HT), &err);
- }
- if (err)
- brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
-
- /* Turn off the bus (F2), free any pending packets */
- brcmf_dbg(INTR, "disable SDIO interrupts\n");
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
- SDIO_FUNC_ENABLE_1, NULL);
-
- /* Clear any pending interrupts now that F2 is disabled */
- w_sdreg32(bus, local_hostintmask,
- offsetof(struct sdpcmd_regs, intstatus), &retries);
-
- /* Turn off the backplane clock (only) */
- brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
-
- /* Clear the data packet queues */
- brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
-
- /* Clear any held glomming stuff */
- if (bus->glomd)
- brcmu_pkt_buf_free_skb(bus->glomd);
-
- if (bus->glom)
- brcmu_pkt_buf_free_skb(bus->glom);
-
- bus->glom = bus->glomd = NULL;
-
- /* Clear rx control and wake any waiters */
- bus->rxlen = 0;
- brcmf_sdbrcm_dcmd_resp_wake(bus);
-
- /* Reset some F2 state stuff */
- bus->rxskip = false;
- bus->tx_seq = bus->rx_seq = 0;
-
- up(&bus->sdsem);
-}
-
-int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr)
-{
- struct brcmf_bus *bus = drvr->bus;
- unsigned long timeout;
- uint retries = 0;
- u8 ready, enable;
- int err, ret = 0;
- u8 saveclk;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* try to download image and nvram to the dongle */
- if (drvr->busstate == BRCMF_BUS_DOWN) {
- if (!(brcmf_sdbrcm_download_firmware(bus)))
- return -1;
- }
-
- if (!bus->drvr)
- return 0;
-
- /* Start the watchdog timer */
- bus->drvr->tickcnt = 0;
- brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
-
- down(&bus->sdsem);
-
- /* Make sure backplane clock is on, needed to generate F2 interrupt */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
- if (bus->clkstate != CLK_AVAIL)
- goto exit;
-
- /* Force clocks on backplane to be sure F2 interrupt propagates */
- saveclk =
- brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, &err);
- if (!err) {
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR,
- (saveclk | SBSDIO_FORCE_HT), &err);
- }
- if (err) {
- brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
- goto exit;
- }
-
- /* Enable function 2 (frame transfers) */
- w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
- offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries);
- enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
- enable, NULL);
-
- timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
- ready = 0;
- while (enable != ready) {
- ready = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_0,
- SDIO_CCCR_IORx, NULL);
- if (time_after(jiffies, timeout))
- break;
- else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50))
- /* prevent busy waiting if it takes too long */
- msleep_interruptible(20);
- }
-
- brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready);
-
- /* If F2 successfully enabled, set core and enable interrupts */
- if (ready == enable) {
- /* Set up the interrupt mask and enable interrupts */
- bus->hostintmask = HOSTINTMASK;
- w_sdreg32(bus, bus->hostintmask,
- offsetof(struct sdpcmd_regs, hostintmask), &retries);
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_WATERMARK, 8, &err);
-
- /* Set bus state according to enable result */
- drvr->busstate = BRCMF_BUS_DATA;
- }
-
- else {
- /* Disable F2 again */
- enable = SDIO_FUNC_ENABLE_1;
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0,
- SDIO_CCCR_IOEx, enable, NULL);
- }
-
- /* Restore previous clock setting */
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
-
- /* If we didn't come up, turn off backplane clock */
- if (drvr->busstate != BRCMF_BUS_DATA)
- brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
-
-exit:
- up(&bus->sdsem);
-
- return ret;
-}
-
-void brcmf_sdbrcm_isr(void *arg)
-{
- struct brcmf_bus *bus = (struct brcmf_bus *) arg;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (!bus) {
- brcmf_dbg(ERROR, "bus is null pointer, exiting\n");
- return;
- }
-
- if (bus->drvr->busstate == BRCMF_BUS_DOWN) {
- brcmf_dbg(ERROR, "bus is down. we have nothing to do\n");
- return;
- }
- /* Count the interrupt call */
- bus->intrcount++;
- bus->ipend = true;
-
- /* Shouldn't get this interrupt if we're sleeping? */
- if (bus->sleeping) {
- brcmf_dbg(ERROR, "INTERRUPT WHILE SLEEPING??\n");
- return;
- }
-
- /* Disable additional interrupts (is this needed now)? */
- if (!bus->intr)
- brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");
-
- bus->dpc_sched = true;
- if (bus->dpc_tsk)
- complete(&bus->dpc_wait);
-}
-
-static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_pub *drvr)
-{
- struct brcmf_bus *bus;
-
- brcmf_dbg(TIMER, "Enter\n");
-
- bus = drvr->bus;
-
- /* Ignore the timer if simulating bus down */
- if (bus->sleeping)
- return false;
-
- down(&bus->sdsem);
-
- /* Poll period: check device if appropriate. */
- if (bus->poll && (++bus->polltick >= bus->pollrate)) {
- u32 intstatus = 0;
-
- /* Reset poll tick */
- bus->polltick = 0;
-
- /* Check device if no interrupts */
- if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
-
- if (!bus->dpc_sched) {
- u8 devpend;
- devpend = brcmf_sdcard_cfg_read(bus->sdiodev,
- SDIO_FUNC_0, SDIO_CCCR_INTx,
- NULL);
- intstatus =
- devpend & (INTR_STATUS_FUNC1 |
- INTR_STATUS_FUNC2);
- }
-
- /* If there is something, make like the ISR and
- schedule the DPC */
- if (intstatus) {
- bus->pollcnt++;
- bus->ipend = true;
-
- bus->dpc_sched = true;
- if (bus->dpc_tsk)
- complete(&bus->dpc_wait);
- }
- }
-
- /* Update interrupt tracking */
- bus->lastintrs = bus->intrcount;
- }
-#ifdef BCMDBG
- /* Poll for console output periodically */
- if (drvr->busstate == BRCMF_BUS_DATA && bus->console_interval != 0) {
- bus->console.count += BRCMF_WD_POLL_MS;
- if (bus->console.count >= bus->console_interval) {
- bus->console.count -= bus->console_interval;
- /* Make sure backplane clock is on */
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
- if (brcmf_sdbrcm_readconsole(bus) < 0)
- /* stop on error */
- bus->console_interval = 0;
- }
- }
-#endif /* BCMDBG */
-
- /* On idle timeout clear activity flag and/or turn off clock */
- if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
- if (++bus->idlecount >= bus->idletime) {
- bus->idlecount = 0;
- if (bus->activity) {
- bus->activity = false;
- brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
- } else {
- brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
- }
- }
- }
-
- up(&bus->sdsem);
-
- return bus->ipend;
-}
-
-static bool brcmf_sdbrcm_chipmatch(u16 chipid)
-{
- if (chipid == BCM4329_CHIP_ID)
- return true;
- return false;
-}
-
-static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- kfree(bus->rxbuf);
- bus->rxctl = bus->rxbuf = NULL;
- bus->rxlen = 0;
-
- kfree(bus->databuf);
- bus->databuf = NULL;
-}
-
-static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- if (bus->drvr->maxctl) {
- bus->rxblen =
- roundup((bus->drvr->maxctl + SDPCM_HDRLEN),
- ALIGNMENT) + BRCMF_SDALIGN;
- bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
- if (!(bus->rxbuf))
- goto fail;
- }
-
- /* Allocate buffer to receive glomed packet */
- bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
- if (!(bus->databuf)) {
- /* release rxbuf which was already located as above */
- if (!bus->rxblen)
- kfree(bus->rxbuf);
- goto fail;
- }
-
- /* Align the buffer */
- if ((unsigned long)bus->databuf % BRCMF_SDALIGN)
- bus->dataptr = bus->databuf + (BRCMF_SDALIGN -
- ((unsigned long)bus->databuf % BRCMF_SDALIGN));
- else
- bus->dataptr = bus->databuf;
-
- return true;
-
-fail:
- return false;
-}
-
-/* SDIO Pad drive strength to select value mappings */
-struct sdiod_drive_str {
- u8 strength; /* Pad Drive Strength in mA */
- u8 sel; /* Chip-specific select value */
-};
-
-/* SDIO Drive Strength to sel value table for PMU Rev 1 */
-static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
- {
- 4, 0x2}, {
- 2, 0x3}, {
- 1, 0x0}, {
- 0, 0x0}
- };
-
-/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
-static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
- {
- 12, 0x7}, {
- 10, 0x6}, {
- 8, 0x5}, {
- 6, 0x4}, {
- 4, 0x2}, {
- 2, 0x1}, {
- 0, 0x0}
- };
-
-/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
-static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
- {
- 32, 0x7}, {
- 26, 0x6}, {
- 22, 0x5}, {
- 16, 0x4}, {
- 12, 0x3}, {
- 8, 0x2}, {
- 4, 0x1}, {
- 0, 0x0}
- };
-
-#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
-
-static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus,
- u32 drivestrength) {
- struct sdiod_drive_str *str_tab = NULL;
- u32 str_mask = 0;
- u32 str_shift = 0;
- char chn[8];
-
- if (!(bus->ci->cccaps & CC_CAP_PMU))
- return;
-
- switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) {
- case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
- str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
- str_mask = 0x30000000;
- str_shift = 28;
- break;
- case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
- case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
- str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
- str_mask = 0x00003800;
- str_shift = 11;
- break;
- case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
- str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
- str_mask = 0x00003800;
- str_shift = 11;
- break;
- default:
- brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
- brcmu_chipname(bus->ci->chip, chn, 8),
- bus->ci->chiprev, bus->ci->pmurev);
- break;
- }
-
- if (str_tab != NULL) {
- u32 drivestrength_sel = 0;
- u32 cc_data_temp;
- int i;
-
- for (i = 0; str_tab[i].strength != 0; i++) {
- if (drivestrength >= str_tab[i].strength) {
- drivestrength_sel = str_tab[i].sel;
- break;
- }
- }
-
- brcmf_sdcard_reg_write(bus->sdiodev,
- CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
- 4, 1);
- cc_data_temp = brcmf_sdcard_reg_read(bus->sdiodev,
- CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4);
- cc_data_temp &= ~str_mask;
- drivestrength_sel <<= str_shift;
- cc_data_temp |= drivestrength_sel;
- brcmf_sdcard_reg_write(bus->sdiodev,
- CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
- 4, cc_data_temp);
-
- brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
- drivestrength, cc_data_temp);
- }
-}
-
-static int
-brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_dev *sdiodev,
- struct chip_info *ci, u32 regs)
-{
- u32 regdata;
-
- /*
- * Get CC core rev
- * Chipid is assume to be at offset 0 from regs arg
- * For different chiptypes or old sdio hosts w/o chipcommon,
- * other ways of recognition should be added here.
- */
- ci->cccorebase = regs;
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_CC_REG(ci->cccorebase, chipid), 4);
- ci->chip = regdata & CID_ID_MASK;
- ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
-
- brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
-
- /* Address of cores for new chips should be added here */
- switch (ci->chip) {
- case BCM4329_CHIP_ID:
- ci->buscorebase = BCM4329_CORE_BUS_BASE;
- ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE;
- ci->armcorebase = BCM4329_CORE_ARM_BASE;
- ci->ramsize = BCM4329_RAMSIZE;
- break;
- default:
- brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
- return -ENODEV;
- }
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(ci->cccorebase, sbidhigh), 4);
- ci->ccrev = SBCOREREV(regdata);
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_CC_REG(ci->cccorebase, pmucapabilities), 4);
- ci->pmurev = regdata & PCAP_REV_MASK;
-
- regdata = brcmf_sdcard_reg_read(sdiodev,
- CORE_SB(ci->buscorebase, sbidhigh), 4);
- ci->buscorerev = SBCOREREV(regdata);
- ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
-
- brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
- ci->ccrev, ci->pmurev, ci->buscorerev, ci->buscoretype);
-
- /* get chipcommon capabilites */
- ci->cccaps = brcmf_sdcard_reg_read(sdiodev,
- CORE_CC_REG(ci->cccorebase, capabilities), 4);
-
- return 0;
-}
-
-static int
-brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs)
-{
- struct chip_info *ci;
- int err;
- u8 clkval, clkset;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* alloc chip_info_t */
- ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
- if (NULL == ci)
- return -ENOMEM;
-
- /* bus/core/clk setup for register access */
- /* Try forcing SDIO core to do ALPAvail request only */
- clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
- if (err) {
- brcmf_dbg(ERROR, "error writing for HT off\n");
- goto fail;
- }
-
- /* If register supported, wait for ALPAvail and then force ALP */
- /* This may take up to 15 milliseconds */
- clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, NULL);
- if ((clkval & ~SBSDIO_AVBITS) == clkset) {
- SPINWAIT(((clkval =
- brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR,
- NULL)),
- !SBSDIO_ALPAV(clkval)),
- PMU_MAX_TRANSITION_DLY);
- if (!SBSDIO_ALPAV(clkval)) {
- brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
- clkval);
- err = -EBUSY;
- goto fail;
- }
- clkset = SBSDIO_FORCE_HW_CLKREQ_OFF |
- SBSDIO_FORCE_ALP;
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR,
- clkset, &err);
- udelay(65);
- } else {
- brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
- clkset, clkval);
- err = -EACCES;
- goto fail;
- }
-
- /* Also, disable the extra SDIO pull-ups */
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
-
- err = brcmf_sdbrcm_chip_recognition(bus->sdiodev, ci, regs);
- if (err)
- goto fail;
-
- /*
- * Make sure any on-chip ARM is off (in case strapping is wrong),
- * or downloaded code was already running.
- */
- brcmf_sdbrcm_chip_disablecore(bus->sdiodev, ci->armcorebase);
-
- brcmf_sdcard_reg_write(bus->sdiodev,
- CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0);
- brcmf_sdcard_reg_write(bus->sdiodev,
- CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0);
-
- /* Disable F2 to clear any intermediate frame state on the dongle */
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
- SDIO_FUNC_ENABLE_1, NULL);
-
- /* WAR: cmd52 backplane read so core HW will drop ALPReq */
- clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- 0, NULL);
-
- /* Done with backplane-dependent accesses, can drop clock... */
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
-
- bus->ci = ci;
- return 0;
-fail:
- bus->ci = NULL;
- kfree(ci);
- return err;
-}
-
-static bool
-brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva)
-{
- u8 clkctl = 0;
- int err = 0;
- int reg_addr;
- u32 reg_val;
-
- bus->alp_only = true;
-
- /* Return the window to backplane enumeration space for core access */
- if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE))
- brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n");
-
-#ifdef BCMDBG
- printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n",
- brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4));
-
-#endif /* BCMDBG */
-
- /*
- * Force PLL off until brcmf_sdbrcm_chip_attach()
- * programs PLL control regs
- */
-
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR,
- BRCMF_INIT_CLKCTL1, &err);
- if (!err)
- clkctl =
- brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, &err);
-
- if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
- brcmf_dbg(ERROR, "ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
- err, BRCMF_INIT_CLKCTL1, clkctl);
- goto fail;
- }
-
- if (brcmf_sdbrcm_chip_attach(bus, regsva)) {
- brcmf_dbg(ERROR, "brcmf_sdbrcm_chip_attach failed!\n");
- goto fail;
- }
-
- if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) {
- brcmf_dbg(ERROR, "unsupported chip: 0x%04x\n", bus->ci->chip);
- goto fail;
- }
-
- brcmf_sdbrcm_sdiod_drive_strength_init(bus, SDIO_DRIVE_STRENGTH);
-
- /* Get info on the ARM and SOCRAM cores... */
- brcmf_sdcard_reg_read(bus->sdiodev,
- CORE_SB(bus->ci->armcorebase, sbidhigh), 4);
- bus->ramsize = bus->ci->ramsize;
- if (!(bus->ramsize)) {
- brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n");
- goto fail;
- }
-
- /* Set core control so an SDIO reset does a backplane reset */
- reg_addr = bus->ci->buscorebase +
- offsetof(struct sdpcmd_regs, corecontrol);
- reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32));
- brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32),
- reg_val | CC_BPRESEN);
-
- brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
-
- /* Locate an appropriately-aligned portion of hdrbuf */
- bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
- BRCMF_SDALIGN);
-
- /* Set the poll and/or interrupt flags */
- bus->intr = true;
- bus->poll = false;
- if (bus->poll)
- bus->pollrate = 1;
-
- return true;
-
-fail:
- return false;
-}
-
-static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- /* Disable F2 to clear any intermediate frame state on the dongle */
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx,
- SDIO_FUNC_ENABLE_1, NULL);
-
- bus->drvr->busstate = BRCMF_BUS_DOWN;
- bus->sleeping = false;
- bus->rxflow = false;
-
- /* Done with backplane-dependent accesses, can drop clock... */
- brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
-
- /* ...and initialize clock/power states */
- bus->clkstate = CLK_SDONLY;
- bus->idletime = BRCMF_IDLE_INTERVAL;
- bus->idleclock = BRCMF_IDLE_ACTIVE;
-
- /* Query the F2 block size, set roundup accordingly */
- bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
- bus->roundup = min(max_roundup, bus->blocksize);
-
- /* bus module does not support packet chaining */
- bus->use_rxchain = false;
- bus->sd_rxchain = false;
-
- return true;
-}
-
-static int
-brcmf_sdbrcm_watchdog_thread(void *data)
-{
- struct brcmf_bus *bus = (struct brcmf_bus *)data;
-
- allow_signal(SIGTERM);
- /* Run until signal received */
- while (1) {
- if (kthread_should_stop())
- break;
- if (!wait_for_completion_interruptible(&bus->watchdog_wait)) {
- brcmf_sdbrcm_bus_watchdog(bus->drvr);
- /* Count the tick for reference */
- bus->drvr->tickcnt++;
- } else
- break;
- }
- return 0;
-}
-
-static void
-brcmf_sdbrcm_watchdog(unsigned long data)
-{
- struct brcmf_bus *bus = (struct brcmf_bus *)data;
-
- if (bus->watchdog_tsk) {
- complete(&bus->watchdog_wait);
- /* Reschedule the watchdog */
- if (bus->wd_timer_valid)
- mod_timer(&bus->timer,
- jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
- }
-}
-
-static void
-brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- kfree(bus->ci);
- bus->ci = NULL;
-}
-
-static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- if (bus->ci) {
- brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
- brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
- brcmf_sdbrcm_chip_detach(bus);
- if (bus->vars && bus->varsz)
- kfree(bus->vars);
- bus->vars = NULL;
- }
-
- brcmf_dbg(TRACE, "Disconnected\n");
-}
-
-/* Detach and free everything */
-static void brcmf_sdbrcm_release(struct brcmf_bus *bus)
-{
- brcmf_dbg(TRACE, "Enter\n");
-
- if (bus) {
- /* De-register interrupt handler */
- brcmf_sdcard_intr_dereg(bus->sdiodev);
-
- if (bus->drvr) {
- brcmf_detach(bus->drvr);
- brcmf_sdbrcm_release_dongle(bus);
- bus->drvr = NULL;
- }
-
- brcmf_sdbrcm_release_malloc(bus);
-
- kfree(bus);
- }
-
- brcmf_dbg(TRACE, "Disconnected\n");
-}
-
-void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype,
- u32 regsva, struct brcmf_sdio_dev *sdiodev)
-{
- int ret;
- struct brcmf_bus *bus;
-
- /* Init global variables at run-time, not as part of the declaration.
- * This is required to support init/de-init of the driver.
- * Initialization
- * of globals as part of the declaration results in non-deterministic
- * behavior since the value of the globals may be different on the
- * first time that the driver is initialized vs subsequent
- * initializations.
- */
- brcmf_c_init();
-
- brcmf_dbg(TRACE, "Enter\n");
-
- /* We make an assumption about address window mappings:
- * regsva == SI_ENUM_BASE*/
-
- /* Allocate private bus interface state */
- bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
- if (!bus)
- goto fail;
-
- bus->sdiodev = sdiodev;
- sdiodev->bus = bus;
- bus->txbound = BRCMF_TXBOUND;
- bus->rxbound = BRCMF_RXBOUND;
- bus->txminmax = BRCMF_TXMINMAX;
- bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
- bus->usebufpool = false; /* Use bufpool if allocated,
- else use locally malloced rxbuf */
-
- /* attempt to attach to the dongle */
- if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) {
- brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n");
- goto fail;
- }
-
- spin_lock_init(&bus->txqlock);
- init_waitqueue_head(&bus->ctrl_wait);
- init_waitqueue_head(&bus->dcmd_resp_wait);
-
- /* Set up the watchdog timer */
- init_timer(&bus->timer);
- bus->timer.data = (unsigned long)bus;
- bus->timer.function = brcmf_sdbrcm_watchdog;
-
- /* Initialize thread based operation and lock */
- sema_init(&bus->sdsem, 1);
-
- /* Initialize watchdog thread */
- init_completion(&bus->watchdog_wait);
- bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
- bus, "brcmf_watchdog");
- if (IS_ERR(bus->watchdog_tsk)) {
- printk(KERN_WARNING
- "brcmf_watchdog thread failed to start\n");
- bus->watchdog_tsk = NULL;
- }
- /* Initialize DPC thread */
- init_completion(&bus->dpc_wait);
- bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
- bus, "brcmf_dpc");
- if (IS_ERR(bus->dpc_tsk)) {
- printk(KERN_WARNING
- "brcmf_dpc thread failed to start\n");
- bus->dpc_tsk = NULL;
- }
-
- /* Attach to the brcmf/OS/network interface */
- bus->drvr = brcmf_attach(bus, SDPCM_RESERVE);
- if (!bus->drvr) {
- brcmf_dbg(ERROR, "brcmf_attach failed\n");
- goto fail;
- }
-
- /* Allocate buffers */
- if (!(brcmf_sdbrcm_probe_malloc(bus))) {
- brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_malloc failed\n");
- goto fail;
- }
-
- if (!(brcmf_sdbrcm_probe_init(bus))) {
- brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_init failed\n");
- goto fail;
- }
-
- /* Register interrupt callback, but mask it (not operational yet). */
- brcmf_dbg(INTR, "disable SDIO interrupts (not interested yet)\n");
- ret = brcmf_sdcard_intr_reg(bus->sdiodev);
- if (ret != 0) {
- brcmf_dbg(ERROR, "FAILED: sdcard_intr_reg returned %d\n", ret);
- goto fail;
- }
- brcmf_dbg(INTR, "registered SDIO interrupt function ok\n");
-
- brcmf_dbg(INFO, "completed!!\n");
-
- /* if firmware path present try to download and bring up bus */
- ret = brcmf_bus_start(bus->drvr);
- if (ret != 0) {
- if (ret == -ENOLINK) {
- brcmf_dbg(ERROR, "dongle is not responding\n");
- goto fail;
- }
- }
- /* Ok, have the per-port tell the stack we're open for business */
- if (brcmf_net_attach(bus->drvr, 0) != 0) {
- brcmf_dbg(ERROR, "Net attach failed!!\n");
- goto fail;
- }
-
- return bus;
-
-fail:
- brcmf_sdbrcm_release(bus);
- return NULL;
-}
-
-void brcmf_sdbrcm_disconnect(void *ptr)
-{
- struct brcmf_bus *bus = (struct brcmf_bus *)ptr;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (bus)
- brcmf_sdbrcm_release(bus);
-
- brcmf_dbg(TRACE, "Disconnected\n");
-}
-
-struct device *brcmf_bus_get_device(struct brcmf_bus *bus)
-{
- return &bus->sdiodev->func[2]->dev;
-}
-
-void
-brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick)
-{
- /* don't start the wd until fw is loaded */
- if (bus->drvr->busstate == BRCMF_BUS_DOWN)
- return;
-
- /* Totally stop the timer */
- if (!wdtick && bus->wd_timer_valid == true) {
- del_timer_sync(&bus->timer);
- bus->wd_timer_valid = false;
- bus->save_ms = wdtick;
- return;
- }
-
- if (wdtick) {
- if (bus->save_ms != BRCMF_WD_POLL_MS) {
- if (bus->wd_timer_valid == true)
- /* Stop timer and restart at new value */
- del_timer_sync(&bus->timer);
-
- /* Create timer again when watchdog period is
- dynamically changed or in the first instance
- */
- bus->timer.expires =
- jiffies + BRCMF_WD_POLL_MS * HZ / 1000;
- add_timer(&bus->timer);
-
- } else {
- /* Re arm the timer, at last watchdog period */
- mod_timer(&bus->timer,
- jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
- }
-
- bus->wd_timer_valid = true;
- bus->save_ms = wdtick;
- }
-}
diff --git a/drivers/staging/brcm80211/brcmfmac/sdio_host.h b/drivers/staging/brcm80211/brcmfmac/sdio_host.h
deleted file mode 100644
index 726fa8981113..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/sdio_host.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _BRCM_SDH_H_
-#define _BRCM_SDH_H_
-
-#include <linux/skbuff.h>
-
-#define SDIO_FUNC_0 0
-#define SDIO_FUNC_1 1
-#define SDIO_FUNC_2 2
-
-#define SDIOD_FBR_SIZE 0x100
-
-/* io_en */
-#define SDIO_FUNC_ENABLE_1 0x02
-#define SDIO_FUNC_ENABLE_2 0x04
-
-/* io_rdys */
-#define SDIO_FUNC_READY_1 0x02
-#define SDIO_FUNC_READY_2 0x04
-
-/* intr_status */
-#define INTR_STATUS_FUNC1 0x2
-#define INTR_STATUS_FUNC2 0x4
-
-/* Maximum number of I/O funcs */
-#define SDIOD_MAX_IOFUNCS 7
-
-/* as of sdiod rev 0, supports 3 functions */
-#define SBSDIO_NUM_FUNCTION 3
-
-/* function 1 miscellaneous registers */
-
-/* sprom command and status */
-#define SBSDIO_SPROM_CS 0x10000
-/* sprom info register */
-#define SBSDIO_SPROM_INFO 0x10001
-/* sprom indirect access data byte 0 */
-#define SBSDIO_SPROM_DATA_LOW 0x10002
-/* sprom indirect access data byte 1 */
-#define SBSDIO_SPROM_DATA_HIGH 0x10003
-/* sprom indirect access addr byte 0 */
-#define SBSDIO_SPROM_ADDR_LOW 0x10004
-/* sprom indirect access addr byte 0 */
-#define SBSDIO_SPROM_ADDR_HIGH 0x10005
-/* xtal_pu (gpio) output */
-#define SBSDIO_CHIP_CTRL_DATA 0x10006
-/* xtal_pu (gpio) enable */
-#define SBSDIO_CHIP_CTRL_EN 0x10007
-/* rev < 7, watermark for sdio device */
-#define SBSDIO_WATERMARK 0x10008
-/* control busy signal generation */
-#define SBSDIO_DEVICE_CTL 0x10009
-
-/* SB Address Window Low (b15) */
-#define SBSDIO_FUNC1_SBADDRLOW 0x1000A
-/* SB Address Window Mid (b23:b16) */
-#define SBSDIO_FUNC1_SBADDRMID 0x1000B
-/* SB Address Window High (b31:b24) */
-#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C
-/* Frame Control (frame term/abort) */
-#define SBSDIO_FUNC1_FRAMECTRL 0x1000D
-/* ChipClockCSR (ALP/HT ctl/status) */
-#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E
-/* SdioPullUp (on cmd, d0-d2) */
-#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F
-/* Write Frame Byte Count Low */
-#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019
-/* Write Frame Byte Count High */
-#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A
-/* Read Frame Byte Count Low */
-#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B
-/* Read Frame Byte Count High */
-#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C
-
-#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */
-#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */
-
-/* function 1 OCP space */
-
-/* sb offset addr is <= 15 bits, 32k */
-#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF
-#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
-/* with b15, maps to 32-bit SB access */
-#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000
-
-/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
-
-#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */
-#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */
-#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */
-/* Address bits from SBADDR regs */
-#define SBSDIO_SBWINDOW_MASK 0xffff8000
-
-#define SDIOH_READ 0 /* Read request */
-#define SDIOH_WRITE 1 /* Write request */
-
-#define SDIOH_DATA_FIX 0 /* Fixed addressing */
-#define SDIOH_DATA_INC 1 /* Incremental addressing */
-
-/* internal return code */
-#define SUCCESS 0
-#define ERROR 1
-
-struct brcmf_sdreg {
- int func;
- int offset;
- int value;
-};
-
-struct brcmf_sdio_dev {
- struct sdio_func *func[SDIO_MAX_FUNCS];
- u8 num_funcs; /* Supported funcs on client */
- u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
- u32 sbwad; /* Save backplane window address */
- bool regfail; /* status of last reg_r/w call */
- void *bus;
- atomic_t suspend; /* suspend flag */
- wait_queue_head_t request_byte_wait;
- wait_queue_head_t request_word_wait;
- wait_queue_head_t request_packet_wait;
- wait_queue_head_t request_buffer_wait;
-
-};
-
-/* Register/deregister device interrupt handler. */
-extern int
-brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev);
-
-extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev);
-
-/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
- * fn: function number
- * addr: unmodified SDIO-space address
- * data: data byte to write
- * err: pointer to error code (or NULL)
- */
-extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint func,
- u32 addr, int *err);
-extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint func,
- u32 addr, u8 data, int *err);
-
-/* Synchronous access to device (client) core registers via CMD53 to F1.
- * addr: backplane address (i.e. >= regsva from attach)
- * size: register width in bytes (2 or 4)
- * data: data for register write
- */
-extern u32
-brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size);
-
-extern u32
-brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
- u32 data);
-
-/* Indicate if last reg read/write failed */
-extern bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev);
-
-/* Buffer transfer to/from device (client) core via cmd53.
- * fn: function number
- * addr: backplane address (i.e. >= regsva from attach)
- * flags: backplane width, address increment, sync/async
- * buf: pointer to memory data buffer
- * nbytes: number of bytes to transfer to/from buf
- * pkt: pointer to packet associated with buf (if any)
- * complete: callback function for command completion (async only)
- * handle: handle for completion callback (first arg in callback)
- * Returns 0 or error code.
- * NOTE: Async operation is not currently supported.
- */
-extern int
-brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
- uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt);
-extern int
-brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
- uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt);
-
-/* Flags bits */
-
-/* Four-byte target (backplane) width (vs. two-byte) */
-#define SDIO_REQ_4BYTE 0x1
-/* Fixed address (FIFO) (vs. incrementing address) */
-#define SDIO_REQ_FIXED 0x2
-/* Async request (vs. sync request) */
-#define SDIO_REQ_ASYNC 0x4
-
-/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
- * rw: read or write (0/1)
- * addr: direct SDIO address
- * buf: pointer to memory data buffer
- * nbytes: number of bytes to transfer to/from buf
- * Returns 0 or error code.
- */
-extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
- u32 addr, u8 *buf, uint nbytes);
-
-/* Issue an abort to the specified function */
-extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
-
-/* platform specific/high level functions */
-extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
-extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
-
-extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
- u32 address);
-
-/* attach, return handler on success, NULL if failed.
- * The handler shall be provided by all subsequent calls. No local cache
- * cfghdl points to the starting address of pci device mapped memory
- */
-extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev);
-extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev);
-
-/* read or write one byte using cmd52 */
-extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw,
- uint fnc, uint addr, u8 *byte);
-
-/* read or write 2/4 bytes using cmd53 */
-extern int
-brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
- uint rw, uint fnc, uint addr,
- u32 *word, uint nbyte);
-
-/* read or write any buffer using cmd53 */
-extern int
-brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
- uint fix_inc, uint rw, uint fnc_num,
- u32 addr, uint regwidth,
- u32 buflen, u8 *buffer, struct sk_buff *pkt);
-
-/* Watchdog timer interface for pm ops */
-extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
- bool enable);
-
-extern void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype,
- u32 regsva, struct brcmf_sdio_dev *sdiodev);
-extern void brcmf_sdbrcm_disconnect(void *ptr);
-extern void brcmf_sdbrcm_isr(void *arg);
-#endif /* _BRCM_SDH_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
deleted file mode 100644
index fc643c1eb59a..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+++ /dev/null
@@ -1,3730 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
-
-#include <linux/kernel.h>
-#include <linux/if_arp.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/netdevice.h>
-#include <linux/bitops.h>
-#include <linux/etherdevice.h>
-#include <linux/ieee80211.h>
-#include <linux/uaccess.h>
-#include <net/cfg80211.h>
-
-#include <brcmu_utils.h>
-#include <defs.h>
-#include <brcmu_wifi.h>
-#include "dhd.h"
-#include "wl_cfg80211.h"
-
-#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
- (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
-
-static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
-
-static u32 brcmf_dbg_level = WL_DBG_ERR;
-
-static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
-{
- dev->driver_data = data;
-}
-
-static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
-{
- void *data = NULL;
-
- if (dev)
- data = dev->driver_data;
- return data;
-}
-
-static
-struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
-{
- struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
- return ci->cfg_priv;
-}
-
-static bool check_sys_up(struct wiphy *wiphy)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
- WL_INFO("device is not ready : status (%d)\n",
- (int)cfg_priv->status);
- return false;
- }
- return true;
-}
-
-#define CHAN2G(_channel, _freq, _flags) { \
- .band = IEEE80211_BAND_2GHZ, \
- .center_freq = (_freq), \
- .hw_value = (_channel), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
-#define CHAN5G(_channel, _flags) { \
- .band = IEEE80211_BAND_5GHZ, \
- .center_freq = 5000 + (5 * (_channel)), \
- .hw_value = (_channel), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
-#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
-#define RATETAB_ENT(_rateid, _flags) \
- { \
- .bitrate = RATE_TO_BASE100KBPS(_rateid), \
- .hw_value = (_rateid), \
- .flags = (_flags), \
- }
-
-static struct ieee80211_rate __wl_rates[] = {
- RATETAB_ENT(BRCM_RATE_1M, 0),
- RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
- RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
- RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
- RATETAB_ENT(BRCM_RATE_6M, 0),
- RATETAB_ENT(BRCM_RATE_9M, 0),
- RATETAB_ENT(BRCM_RATE_12M, 0),
- RATETAB_ENT(BRCM_RATE_18M, 0),
- RATETAB_ENT(BRCM_RATE_24M, 0),
- RATETAB_ENT(BRCM_RATE_36M, 0),
- RATETAB_ENT(BRCM_RATE_48M, 0),
- RATETAB_ENT(BRCM_RATE_54M, 0),
-};
-
-#define wl_a_rates (__wl_rates + 4)
-#define wl_a_rates_size 8
-#define wl_g_rates (__wl_rates + 0)
-#define wl_g_rates_size 12
-
-static struct ieee80211_channel __wl_2ghz_channels[] = {
- CHAN2G(1, 2412, 0),
- CHAN2G(2, 2417, 0),
- CHAN2G(3, 2422, 0),
- CHAN2G(4, 2427, 0),
- CHAN2G(5, 2432, 0),
- CHAN2G(6, 2437, 0),
- CHAN2G(7, 2442, 0),
- CHAN2G(8, 2447, 0),
- CHAN2G(9, 2452, 0),
- CHAN2G(10, 2457, 0),
- CHAN2G(11, 2462, 0),
- CHAN2G(12, 2467, 0),
- CHAN2G(13, 2472, 0),
- CHAN2G(14, 2484, 0),
-};
-
-static struct ieee80211_channel __wl_5ghz_a_channels[] = {
- CHAN5G(34, 0), CHAN5G(36, 0),
- CHAN5G(38, 0), CHAN5G(40, 0),
- CHAN5G(42, 0), CHAN5G(44, 0),
- CHAN5G(46, 0), CHAN5G(48, 0),
- CHAN5G(52, 0), CHAN5G(56, 0),
- CHAN5G(60, 0), CHAN5G(64, 0),
- CHAN5G(100, 0), CHAN5G(104, 0),
- CHAN5G(108, 0), CHAN5G(112, 0),
- CHAN5G(116, 0), CHAN5G(120, 0),
- CHAN5G(124, 0), CHAN5G(128, 0),
- CHAN5G(132, 0), CHAN5G(136, 0),
- CHAN5G(140, 0), CHAN5G(149, 0),
- CHAN5G(153, 0), CHAN5G(157, 0),
- CHAN5G(161, 0), CHAN5G(165, 0),
- CHAN5G(184, 0), CHAN5G(188, 0),
- CHAN5G(192, 0), CHAN5G(196, 0),
- CHAN5G(200, 0), CHAN5G(204, 0),
- CHAN5G(208, 0), CHAN5G(212, 0),
- CHAN5G(216, 0),
-};
-
-static struct ieee80211_channel __wl_5ghz_n_channels[] = {
- CHAN5G(32, 0), CHAN5G(34, 0),
- CHAN5G(36, 0), CHAN5G(38, 0),
- CHAN5G(40, 0), CHAN5G(42, 0),
- CHAN5G(44, 0), CHAN5G(46, 0),
- CHAN5G(48, 0), CHAN5G(50, 0),
- CHAN5G(52, 0), CHAN5G(54, 0),
- CHAN5G(56, 0), CHAN5G(58, 0),
- CHAN5G(60, 0), CHAN5G(62, 0),
- CHAN5G(64, 0), CHAN5G(66, 0),
- CHAN5G(68, 0), CHAN5G(70, 0),
- CHAN5G(72, 0), CHAN5G(74, 0),
- CHAN5G(76, 0), CHAN5G(78, 0),
- CHAN5G(80, 0), CHAN5G(82, 0),
- CHAN5G(84, 0), CHAN5G(86, 0),
- CHAN5G(88, 0), CHAN5G(90, 0),
- CHAN5G(92, 0), CHAN5G(94, 0),
- CHAN5G(96, 0), CHAN5G(98, 0),
- CHAN5G(100, 0), CHAN5G(102, 0),
- CHAN5G(104, 0), CHAN5G(106, 0),
- CHAN5G(108, 0), CHAN5G(110, 0),
- CHAN5G(112, 0), CHAN5G(114, 0),
- CHAN5G(116, 0), CHAN5G(118, 0),
- CHAN5G(120, 0), CHAN5G(122, 0),
- CHAN5G(124, 0), CHAN5G(126, 0),
- CHAN5G(128, 0), CHAN5G(130, 0),
- CHAN5G(132, 0), CHAN5G(134, 0),
- CHAN5G(136, 0), CHAN5G(138, 0),
- CHAN5G(140, 0), CHAN5G(142, 0),
- CHAN5G(144, 0), CHAN5G(145, 0),
- CHAN5G(146, 0), CHAN5G(147, 0),
- CHAN5G(148, 0), CHAN5G(149, 0),
- CHAN5G(150, 0), CHAN5G(151, 0),
- CHAN5G(152, 0), CHAN5G(153, 0),
- CHAN5G(154, 0), CHAN5G(155, 0),
- CHAN5G(156, 0), CHAN5G(157, 0),
- CHAN5G(158, 0), CHAN5G(159, 0),
- CHAN5G(160, 0), CHAN5G(161, 0),
- CHAN5G(162, 0), CHAN5G(163, 0),
- CHAN5G(164, 0), CHAN5G(165, 0),
- CHAN5G(166, 0), CHAN5G(168, 0),
- CHAN5G(170, 0), CHAN5G(172, 0),
- CHAN5G(174, 0), CHAN5G(176, 0),
- CHAN5G(178, 0), CHAN5G(180, 0),
- CHAN5G(182, 0), CHAN5G(184, 0),
- CHAN5G(186, 0), CHAN5G(188, 0),
- CHAN5G(190, 0), CHAN5G(192, 0),
- CHAN5G(194, 0), CHAN5G(196, 0),
- CHAN5G(198, 0), CHAN5G(200, 0),
- CHAN5G(202, 0), CHAN5G(204, 0),
- CHAN5G(206, 0), CHAN5G(208, 0),
- CHAN5G(210, 0), CHAN5G(212, 0),
- CHAN5G(214, 0), CHAN5G(216, 0),
- CHAN5G(218, 0), CHAN5G(220, 0),
- CHAN5G(222, 0), CHAN5G(224, 0),
- CHAN5G(226, 0), CHAN5G(228, 0),
-};
-
-static struct ieee80211_supported_band __wl_band_2ghz = {
- .band = IEEE80211_BAND_2GHZ,
- .channels = __wl_2ghz_channels,
- .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
- .bitrates = wl_g_rates,
- .n_bitrates = wl_g_rates_size,
-};
-
-static struct ieee80211_supported_band __wl_band_5ghz_a = {
- .band = IEEE80211_BAND_5GHZ,
- .channels = __wl_5ghz_a_channels,
- .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
- .bitrates = wl_a_rates,
- .n_bitrates = wl_a_rates_size,
-};
-
-static struct ieee80211_supported_band __wl_band_5ghz_n = {
- .band = IEEE80211_BAND_5GHZ,
- .channels = __wl_5ghz_n_channels,
- .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
- .bitrates = wl_a_rates,
- .n_bitrates = wl_a_rates_size,
-};
-
-static const u32 __wl_cipher_suites[] = {
- WLAN_CIPHER_SUITE_WEP40,
- WLAN_CIPHER_SUITE_WEP104,
- WLAN_CIPHER_SUITE_TKIP,
- WLAN_CIPHER_SUITE_CCMP,
- WLAN_CIPHER_SUITE_AES_CMAC,
-};
-
-/* function for reading/writing a single u32 from/to the dongle */
-static int
-brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
-{
- int err;
- __le32 par_le = cpu_to_le32(*par);
-
- err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
- *par = le32_to_cpu(par_le);
-
- return err;
-}
-
-static void convert_key_from_CPU(struct brcmf_wsec_key *key,
- struct brcmf_wsec_key_le *key_le)
-{
- key_le->index = cpu_to_le32(key->index);
- key_le->len = cpu_to_le32(key->len);
- key_le->algo = cpu_to_le32(key->algo);
- key_le->flags = cpu_to_le32(key->flags);
- key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
- key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
- key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
- memcpy(key_le->data, key->data, sizeof(key->data));
- memcpy(key_le->ea, key->ea, sizeof(key->ea));
-}
-
-static int send_key_to_dongle(struct net_device *ndev,
- struct brcmf_wsec_key *key)
-{
- int err;
- struct brcmf_wsec_key_le key_le;
-
- convert_key_from_CPU(key, &key_le);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
- if (err)
- WL_ERR("WLC_SET_KEY error (%d)\n", err);
- return err;
-}
-
-static s32
-brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct wireless_dev *wdev;
- s32 infra = 0;
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- switch (type) {
- case NL80211_IFTYPE_MONITOR:
- case NL80211_IFTYPE_WDS:
- WL_ERR("type (%d) : currently we do not support this type\n",
- type);
- return -EOPNOTSUPP;
- case NL80211_IFTYPE_ADHOC:
- cfg_priv->conf->mode = WL_MODE_IBSS;
- infra = 0;
- break;
- case NL80211_IFTYPE_STATION:
- cfg_priv->conf->mode = WL_MODE_BSS;
- infra = 1;
- break;
- default:
- err = -EINVAL;
- goto done;
- }
-
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
- if (err) {
- WL_ERR("WLC_SET_INFRA error (%d)\n", err);
- err = -EAGAIN;
- } else {
- wdev = ndev->ieee80211_ptr;
- wdev->iftype = type;
- }
-
- WL_INFO("IF Type = %s\n",
- (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
-
-done:
- WL_TRACE("Exit\n");
-
- return err;
-}
-
-static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
-{
- s8 buf[BRCMF_DCMD_SMLEN];
- u32 len;
- s32 err = 0;
- __le32 val_le;
-
- val_le = cpu_to_le32(val);
- len = brcmu_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
- sizeof(buf));
- BUG_ON(!len);
-
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
- if (err)
- WL_ERR("error (%d)\n", err);
-
- return err;
-}
-
-static s32
-brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
-{
- union {
- s8 buf[BRCMF_DCMD_SMLEN];
- __le32 val;
- } var;
- u32 len;
- u32 data_null;
- s32 err = 0;
-
- len =
- brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
- sizeof(var.buf));
- BUG_ON(!len);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
- if (err)
- WL_ERR("error (%d)\n", err);
-
- *retval = le32_to_cpu(var.val);
-
- return err;
-}
-
-static void brcmf_set_mpc(struct net_device *ndev, int mpc)
-{
- s32 err = 0;
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
-
- if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
- err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
- if (err) {
- WL_ERR("fail to set mpc\n");
- return;
- }
- WL_INFO("MPC : %d\n", mpc);
- }
-}
-
-static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
- struct brcmf_ssid *ssid)
-{
- memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
- params_le->bss_type = DOT11_BSSTYPE_ANY;
- params_le->scan_type = 0;
- params_le->channel_num = 0;
- params_le->nprobes = cpu_to_le32(-1);
- params_le->active_time = cpu_to_le32(-1);
- params_le->passive_time = cpu_to_le32(-1);
- params_le->home_time = cpu_to_le32(-1);
- if (ssid && ssid->SSID_len)
- memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
-}
-
-static s32
-brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
- s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 iolen;
-
- iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
- BUG_ON(!iolen);
-
- return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
-}
-
-static s32
-brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
- s32 paramlen, void *bufptr, s32 buflen)
-{
- s32 iolen;
-
- iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
- BUG_ON(!iolen);
-
- return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
-}
-
-static s32
-brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
- struct brcmf_ssid *ssid, u16 action)
-{
- s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
- offsetof(struct brcmf_iscan_params_le, params_le);
- struct brcmf_iscan_params_le *params;
- s32 err = 0;
-
- if (ssid && ssid->SSID_len)
- params_size += sizeof(struct brcmf_ssid);
- params = kzalloc(params_size, GFP_KERNEL);
- if (!params)
- return -ENOMEM;
- BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
-
- wl_iscan_prep(&params->params_le, ssid);
-
- params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
- params->action = cpu_to_le16(action);
- params->scan_duration = cpu_to_le16(0);
-
- err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
- iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
- if (err) {
- if (err == -EBUSY)
- WL_INFO("system busy : iscan canceled\n");
- else
- WL_ERR("error (%d)\n", err);
- }
-
- kfree(params);
- return err;
-}
-
-static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
- struct net_device *ndev = cfg_to_ndev(cfg_priv);
- struct brcmf_ssid ssid;
- s32 passive_scan;
- s32 err = 0;
-
- /* Broadcast scan by default */
- memset(&ssid, 0, sizeof(ssid));
-
- iscan->state = WL_ISCAN_STATE_SCANING;
-
- passive_scan = cfg_priv->active_scan ? 0 : 1;
- err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
- if (err) {
- WL_ERR("error (%d)\n", err);
- return err;
- }
- brcmf_set_mpc(ndev, 0);
- cfg_priv->iscan_kickstart = true;
- err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
- if (err) {
- brcmf_set_mpc(ndev, 1);
- cfg_priv->iscan_kickstart = false;
- return err;
- }
- mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
- iscan->timer_on = 1;
- return err;
-}
-
-static s32
-__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_scan_request *request,
- struct cfg80211_ssid *this_ssid)
-{
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
- struct cfg80211_ssid *ssids;
- struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
- s32 passive_scan;
- bool iscan_req;
- bool spec_scan;
- s32 err = 0;
- u32 SSID_len;
-
- if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
- WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
- return -EAGAIN;
- }
- if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
- WL_ERR("Scanning being aborted : status (%lu)\n",
- cfg_priv->status);
- return -EAGAIN;
- }
- if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
- WL_ERR("Connecting : status (%lu)\n",
- cfg_priv->status);
- return -EAGAIN;
- }
-
- iscan_req = false;
- spec_scan = false;
- if (request) {
- /* scan bss */
- ssids = request->ssids;
- if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
- iscan_req = true;
- } else {
- /* scan in ibss */
- /* we don't do iscan in ibss */
- ssids = this_ssid;
- }
-
- cfg_priv->scan_request = request;
- set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
- if (iscan_req) {
- err = brcmf_do_iscan(cfg_priv);
- if (!err)
- return err;
- else
- goto scan_out;
- } else {
- WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
- ssids->ssid, ssids->ssid_len);
- memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
- SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
- sr->ssid_le.SSID_len = cpu_to_le32(0);
- if (SSID_len) {
- memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
- sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
- spec_scan = true;
- } else {
- WL_SCAN("Broadcast scan\n");
- }
-
- passive_scan = cfg_priv->active_scan ? 0 : 1;
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
- &passive_scan, sizeof(passive_scan));
- if (err) {
- WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
- goto scan_out;
- }
- brcmf_set_mpc(ndev, 0);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
- sizeof(sr->ssid_le));
- if (err) {
- if (err == -EBUSY)
- WL_INFO("system busy : scan for \"%s\" "
- "canceled\n", sr->ssid_le.SSID);
- else
- WL_ERR("WLC_SCAN error (%d)\n", err);
-
- brcmf_set_mpc(ndev, 1);
- goto scan_out;
- }
- }
-
- return 0;
-
-scan_out:
- clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
- cfg_priv->scan_request = NULL;
- return err;
-}
-
-static s32
-brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_scan_request *request)
-{
- s32 err = 0;
-
- WL_TRACE("Enter\n");
-
- if (!check_sys_up(wiphy))
- return -EIO;
-
- err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
- if (err)
- WL_ERR("scan error (%d)\n", err);
-
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
-{
- s32 err = 0;
-
- err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
- if (err)
- WL_ERR("Error (%d)\n", err);
-
- return err;
-}
-
-static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
-{
- s32 err = 0;
-
- err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
- if (err)
- WL_ERR("Error (%d)\n", err);
-
- return err;
-}
-
-static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
-{
- s32 err = 0;
- u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
-
- err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
- if (err) {
- WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
- return err;
- }
- return err;
-}
-
-static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct net_device *ndev = cfg_to_ndev(cfg_priv);
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
- (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
- cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
- err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
- if (!err)
- goto done;
- }
- if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
- (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
- cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
- err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
- if (!err)
- goto done;
- }
- if (changed & WIPHY_PARAM_RETRY_LONG
- && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
- cfg_priv->conf->retry_long = wiphy->retry_long;
- err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
- if (!err)
- goto done;
- }
- if (changed & WIPHY_PARAM_RETRY_SHORT
- && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
- cfg_priv->conf->retry_short = wiphy->retry_short;
- err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
- if (!err)
- goto done;
- }
-
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
-{
- switch (item) {
- case WL_PROF_SEC:
- return &cfg_priv->profile->sec;
- case WL_PROF_BSSID:
- return &cfg_priv->profile->bssid;
- case WL_PROF_SSID:
- return &cfg_priv->profile->ssid;
- }
- WL_ERR("invalid item (%d)\n", item);
- return NULL;
-}
-
-static s32
-brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
- const struct brcmf_event_msg *e, void *data, s32 item)
-{
- s32 err = 0;
- struct brcmf_ssid *ssid;
-
- switch (item) {
- case WL_PROF_SSID:
- ssid = (struct brcmf_ssid *) data;
- memset(cfg_priv->profile->ssid.SSID, 0,
- sizeof(cfg_priv->profile->ssid.SSID));
- memcpy(cfg_priv->profile->ssid.SSID,
- ssid->SSID, ssid->SSID_len);
- cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
- break;
- case WL_PROF_BSSID:
- if (data)
- memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
- else
- memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
- break;
- case WL_PROF_SEC:
- memcpy(&cfg_priv->profile->sec, data,
- sizeof(cfg_priv->profile->sec));
- break;
- case WL_PROF_BEACONINT:
- cfg_priv->profile->beacon_interval = *(u16 *)data;
- break;
- case WL_PROF_DTIMPERIOD:
- cfg_priv->profile->dtim_period = *(u8 *)data;
- break;
- default:
- WL_ERR("unsupported item (%d)\n", item);
- err = -EOPNOTSUPP;
- break;
- }
-
- return err;
-}
-
-static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
-{
- memset(prof, 0, sizeof(*prof));
-}
-
-static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
- size_t *join_params_size)
-{
- u16 chanspec = 0;
-
- if (ch != 0) {
- if (ch <= CH_MAX_2G_CHANNEL)
- chanspec |= WL_CHANSPEC_BAND_2G;
- else
- chanspec |= WL_CHANSPEC_BAND_5G;
-
- chanspec |= WL_CHANSPEC_BW_20;
- chanspec |= WL_CHANSPEC_CTL_SB_NONE;
-
- *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
- sizeof(u16);
-
- chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
- join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
- join_params->params_le.chanspec_num = cpu_to_le32(1);
-
- WL_CONN("join_params->params.chanspec_list[0]= %#X,"
- "channel %d, chanspec %#X\n",
- chanspec, ch, chanspec);
- }
-}
-
-static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct net_device *ndev = NULL;
- s32 err = 0;
-
- WL_TRACE("Enter\n");
-
- if (cfg_priv->link_up) {
- ndev = cfg_to_ndev(cfg_priv);
- WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
- err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
- if (err)
- WL_ERR("WLC_DISASSOC failed (%d)\n", err);
- cfg_priv->link_up = false;
- }
- WL_TRACE("Exit\n");
-}
-
-static s32
-brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_ibss_params *params)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct brcmf_join_params join_params;
- size_t join_params_size = 0;
- s32 err = 0;
- s32 wsec = 0;
- s32 bcnprd;
- struct brcmf_ssid ssid;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- if (params->ssid)
- WL_CONN("SSID: %s\n", params->ssid);
- else {
- WL_CONN("SSID: NULL, Not supported\n");
- return -EOPNOTSUPP;
- }
-
- set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
-
- if (params->bssid)
- WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
- params->bssid[0], params->bssid[1], params->bssid[2],
- params->bssid[3], params->bssid[4], params->bssid[5]);
- else
- WL_CONN("No BSSID specified\n");
-
- if (params->channel)
- WL_CONN("channel: %d\n", params->channel->center_freq);
- else
- WL_CONN("no channel specified\n");
-
- if (params->channel_fixed)
- WL_CONN("fixed channel required\n");
- else
- WL_CONN("no fixed channel required\n");
-
- if (params->ie && params->ie_len)
- WL_CONN("ie len: %d\n", params->ie_len);
- else
- WL_CONN("no ie specified\n");
-
- if (params->beacon_interval)
- WL_CONN("beacon interval: %d\n", params->beacon_interval);
- else
- WL_CONN("no beacon interval specified\n");
-
- if (params->basic_rates)
- WL_CONN("basic rates: %08X\n", params->basic_rates);
- else
- WL_CONN("no basic rates specified\n");
-
- if (params->privacy)
- WL_CONN("privacy required\n");
- else
- WL_CONN("no privacy required\n");
-
- /* Configure Privacy for starter */
- if (params->privacy)
- wsec |= WEP_ENABLED;
-
- err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
- if (err) {
- WL_ERR("wsec failed (%d)\n", err);
- goto done;
- }
-
- /* Configure Beacon Interval for starter */
- if (params->beacon_interval)
- bcnprd = params->beacon_interval;
- else
- bcnprd = 100;
-
- err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
- if (err) {
- WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
- goto done;
- }
-
- /* Configure required join parameter */
- memset(&join_params, 0, sizeof(struct brcmf_join_params));
-
- /* SSID */
- ssid.SSID_len = min_t(u32, params->ssid_len, 32);
- memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
- memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
- join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
- join_params_size = sizeof(join_params.ssid_le);
- brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
-
- /* BSSID */
- if (params->bssid) {
- memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
- join_params_size = sizeof(join_params.ssid_le) +
- BRCMF_ASSOC_PARAMS_FIXED_SIZE;
- } else {
- memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
- }
-
- brcmf_update_prof(cfg_priv, NULL,
- &join_params.params_le.bssid, WL_PROF_BSSID);
-
- /* Channel */
- if (params->channel) {
- u32 target_channel;
-
- cfg_priv->channel =
- ieee80211_frequency_to_channel(
- params->channel->center_freq);
- if (params->channel_fixed) {
- /* adding chanspec */
- brcmf_ch_to_chanspec(cfg_priv->channel,
- &join_params, &join_params_size);
- }
-
- /* set channel for starter */
- target_channel = cfg_priv->channel;
- err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
- &target_channel);
- if (err) {
- WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
- goto done;
- }
- } else
- cfg_priv->channel = 0;
-
- cfg_priv->ibss_starter = false;
-
-
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
- &join_params, join_params_size);
- if (err) {
- WL_ERR("WLC_SET_SSID failed (%d)\n", err);
- goto done;
- }
-
-done:
- if (err)
- clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- brcmf_link_down(cfg_priv);
-
- WL_TRACE("Exit\n");
-
- return err;
-}
-
-static s32 brcmf_set_wpa_version(struct net_device *ndev,
- struct cfg80211_connect_params *sme)
-{
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_security *sec;
- s32 val = 0;
- s32 err = 0;
-
- if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
- val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
- else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
- val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
- else
- val = WPA_AUTH_DISABLED;
- WL_CONN("setting wpa_auth to 0x%0x\n", val);
- err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
- if (err) {
- WL_ERR("set wpa_auth failed (%d)\n", err);
- return err;
- }
- sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
- sec->wpa_versions = sme->crypto.wpa_versions;
- return err;
-}
-
-static s32 brcmf_set_auth_type(struct net_device *ndev,
- struct cfg80211_connect_params *sme)
-{
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_security *sec;
- s32 val = 0;
- s32 err = 0;
-
- switch (sme->auth_type) {
- case NL80211_AUTHTYPE_OPEN_SYSTEM:
- val = 0;
- WL_CONN("open system\n");
- break;
- case NL80211_AUTHTYPE_SHARED_KEY:
- val = 1;
- WL_CONN("shared key\n");
- break;
- case NL80211_AUTHTYPE_AUTOMATIC:
- val = 2;
- WL_CONN("automatic\n");
- break;
- case NL80211_AUTHTYPE_NETWORK_EAP:
- WL_CONN("network eap\n");
- default:
- val = 2;
- WL_ERR("invalid auth type (%d)\n", sme->auth_type);
- break;
- }
-
- err = brcmf_dev_intvar_set(ndev, "auth", val);
- if (err) {
- WL_ERR("set auth failed (%d)\n", err);
- return err;
- }
- sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
- sec->auth_type = sme->auth_type;
- return err;
-}
-
-static s32
-brcmf_set_set_cipher(struct net_device *ndev,
- struct cfg80211_connect_params *sme)
-{
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_security *sec;
- s32 pval = 0;
- s32 gval = 0;
- s32 err = 0;
-
- if (sme->crypto.n_ciphers_pairwise) {
- switch (sme->crypto.ciphers_pairwise[0]) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- pval = WEP_ENABLED;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- pval = TKIP_ENABLED;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- pval = AES_ENABLED;
- break;
- case WLAN_CIPHER_SUITE_AES_CMAC:
- pval = AES_ENABLED;
- break;
- default:
- WL_ERR("invalid cipher pairwise (%d)\n",
- sme->crypto.ciphers_pairwise[0]);
- return -EINVAL;
- }
- }
- if (sme->crypto.cipher_group) {
- switch (sme->crypto.cipher_group) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- gval = WEP_ENABLED;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- gval = TKIP_ENABLED;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- gval = AES_ENABLED;
- break;
- case WLAN_CIPHER_SUITE_AES_CMAC:
- gval = AES_ENABLED;
- break;
- default:
- WL_ERR("invalid cipher group (%d)\n",
- sme->crypto.cipher_group);
- return -EINVAL;
- }
- }
-
- WL_CONN("pval (%d) gval (%d)\n", pval, gval);
- err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
- if (err) {
- WL_ERR("error (%d)\n", err);
- return err;
- }
-
- sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
- sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
- sec->cipher_group = sme->crypto.cipher_group;
-
- return err;
-}
-
-static s32
-brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
-{
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_security *sec;
- s32 val = 0;
- s32 err = 0;
-
- if (sme->crypto.n_akm_suites) {
- err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
- if (err) {
- WL_ERR("could not get wpa_auth (%d)\n", err);
- return err;
- }
- if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
- switch (sme->crypto.akm_suites[0]) {
- case WLAN_AKM_SUITE_8021X:
- val = WPA_AUTH_UNSPECIFIED;
- break;
- case WLAN_AKM_SUITE_PSK:
- val = WPA_AUTH_PSK;
- break;
- default:
- WL_ERR("invalid cipher group (%d)\n",
- sme->crypto.cipher_group);
- return -EINVAL;
- }
- } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
- switch (sme->crypto.akm_suites[0]) {
- case WLAN_AKM_SUITE_8021X:
- val = WPA2_AUTH_UNSPECIFIED;
- break;
- case WLAN_AKM_SUITE_PSK:
- val = WPA2_AUTH_PSK;
- break;
- default:
- WL_ERR("invalid cipher group (%d)\n",
- sme->crypto.cipher_group);
- return -EINVAL;
- }
- }
-
- WL_CONN("setting wpa_auth to %d\n", val);
- err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
- if (err) {
- WL_ERR("could not set wpa_auth (%d)\n", err);
- return err;
- }
- }
- sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
- sec->wpa_auth = sme->crypto.akm_suites[0];
-
- return err;
-}
-
-static s32
-brcmf_set_set_sharedkey(struct net_device *ndev,
- struct cfg80211_connect_params *sme)
-{
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
- struct brcmf_cfg80211_security *sec;
- struct brcmf_wsec_key key;
- s32 val;
- s32 err = 0;
-
- WL_CONN("key len (%d)\n", sme->key_len);
- if (sme->key_len) {
- sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
- WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
- sec->wpa_versions, sec->cipher_pairwise);
- if (!
- (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
- NL80211_WPA_VERSION_2))
-&& (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
- WLAN_CIPHER_SUITE_WEP104))) {
- memset(&key, 0, sizeof(key));
- key.len = (u32) sme->key_len;
- key.index = (u32) sme->key_idx;
- if (key.len > sizeof(key.data)) {
- WL_ERR("Too long key length (%u)\n", key.len);
- return -EINVAL;
- }
- memcpy(key.data, sme->key, key.len);
- key.flags = BRCMF_PRIMARY_KEY;
- switch (sec->cipher_pairwise) {
- case WLAN_CIPHER_SUITE_WEP40:
- key.algo = CRYPTO_ALGO_WEP1;
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- key.algo = CRYPTO_ALGO_WEP128;
- break;
- default:
- WL_ERR("Invalid algorithm (%d)\n",
- sme->crypto.ciphers_pairwise[0]);
- return -EINVAL;
- }
- /* Set the new key/index */
- WL_CONN("key length (%d) key index (%d) algo (%d)\n",
- key.len, key.index, key.algo);
- WL_CONN("key \"%s\"\n", key.data);
- err = send_key_to_dongle(ndev, &key);
- if (err)
- return err;
-
- if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
- WL_CONN("set auth_type to shared key\n");
- val = 1; /* shared key */
- err = brcmf_dev_intvar_set(ndev, "auth", val);
- if (err) {
- WL_ERR("set auth failed (%d)\n", err);
- return err;
- }
- }
- }
- }
- return err;
-}
-
-static s32
-brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_connect_params *sme)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct ieee80211_channel *chan = sme->channel;
- struct brcmf_join_params join_params;
- size_t join_params_size;
- struct brcmf_ssid ssid;
-
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- if (!sme->ssid) {
- WL_ERR("Invalid ssid\n");
- return -EOPNOTSUPP;
- }
-
- set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
-
- if (chan) {
- cfg_priv->channel =
- ieee80211_frequency_to_channel(chan->center_freq);
- WL_CONN("channel (%d), center_req (%d)\n",
- cfg_priv->channel, chan->center_freq);
- } else
- cfg_priv->channel = 0;
-
- WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
-
- err = brcmf_set_wpa_version(ndev, sme);
- if (err) {
- WL_ERR("wl_set_wpa_version failed (%d)\n", err);
- goto done;
- }
-
- err = brcmf_set_auth_type(ndev, sme);
- if (err) {
- WL_ERR("wl_set_auth_type failed (%d)\n", err);
- goto done;
- }
-
- err = brcmf_set_set_cipher(ndev, sme);
- if (err) {
- WL_ERR("wl_set_set_cipher failed (%d)\n", err);
- goto done;
- }
-
- err = brcmf_set_key_mgmt(ndev, sme);
- if (err) {
- WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
- goto done;
- }
-
- err = brcmf_set_set_sharedkey(ndev, sme);
- if (err) {
- WL_ERR("wl_set_set_sharedkey failed (%d)\n", err);
- goto done;
- }
-
- memset(&join_params, 0, sizeof(join_params));
- join_params_size = sizeof(join_params.ssid_le);
-
- ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len);
- memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
- memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
- join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
- brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
-
- memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
-
- if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
- WL_CONN("ssid \"%s\", len (%d)\n",
- ssid.SSID, ssid.SSID_len);
-
- brcmf_ch_to_chanspec(cfg_priv->channel,
- &join_params, &join_params_size);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
- &join_params, join_params_size);
- if (err)
- WL_ERR("WLC_SET_SSID failed (%d)\n", err);
-
-done:
- if (err)
- clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
- u16 reason_code)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct brcmf_scb_val_le scbval;
- s32 err = 0;
-
- WL_TRACE("Enter. Reason code = %d\n", reason_code);
- if (!check_sys_up(wiphy))
- return -EIO;
-
- clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
-
- memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
- scbval.val = cpu_to_le32(reason_code);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
- sizeof(struct brcmf_scb_val_le));
- if (err)
- WL_ERR("error (%d)\n", err);
-
- cfg_priv->link_up = false;
-
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
- enum nl80211_tx_power_setting type, s32 dbm)
-{
-
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct net_device *ndev = cfg_to_ndev(cfg_priv);
- u16 txpwrmw;
- s32 err = 0;
- s32 disable = 0;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- switch (type) {
- case NL80211_TX_POWER_AUTOMATIC:
- break;
- case NL80211_TX_POWER_LIMITED:
- if (dbm < 0) {
- WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
- err = -EINVAL;
- goto done;
- }
- break;
- case NL80211_TX_POWER_FIXED:
- if (dbm < 0) {
- WL_ERR("TX_POWER_FIXED - dbm is negative\n");
- err = -EINVAL;
- goto done;
- }
- break;
- }
- /* Make sure radio is off or on as far as software is concerned */
- disable = WL_RADIO_SW_DISABLE << 16;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
- if (err)
- WL_ERR("WLC_SET_RADIO error (%d)\n", err);
-
- if (dbm > 0xffff)
- txpwrmw = 0xffff;
- else
- txpwrmw = (u16) dbm;
- err = brcmf_dev_intvar_set(ndev, "qtxpower",
- (s32) (brcmu_mw_to_qdbm(txpwrmw)));
- if (err)
- WL_ERR("qtxpower error (%d)\n", err);
- cfg_priv->conf->tx_power = dbm;
-
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct net_device *ndev = cfg_to_ndev(cfg_priv);
- s32 txpwrdbm;
- u8 result;
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
- if (err) {
- WL_ERR("error (%d)\n", err);
- goto done;
- }
-
- result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
- *dbm = (s32) brcmu_qdbm_to_mw(result);
-
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_idx, bool unicast, bool multicast)
-{
- u32 index;
- u32 wsec;
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- WL_CONN("key index (%d)\n", key_idx);
- if (!check_sys_up(wiphy))
- return -EIO;
-
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
- if (err) {
- WL_ERR("WLC_GET_WSEC error (%d)\n", err);
- goto done;
- }
-
- if (wsec & WEP_ENABLED) {
- /* Just select a new current key */
- index = key_idx;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
- &index);
- if (err)
- WL_ERR("error (%d)\n", err);
- }
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_idx, const u8 *mac_addr, struct key_params *params)
-{
- struct brcmf_wsec_key key;
- struct brcmf_wsec_key_le key_le;
- s32 err = 0;
-
- memset(&key, 0, sizeof(key));
- key.index = (u32) key_idx;
- /* Instead of bcast for ea address for default wep keys,
- driver needs it to be Null */
- if (!is_multicast_ether_addr(mac_addr))
- memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
- key.len = (u32) params->key_len;
- /* check for key index change */
- if (key.len == 0) {
- /* key delete */
- err = send_key_to_dongle(ndev, &key);
- if (err)
- return err;
- } else {
- if (key.len > sizeof(key.data)) {
- WL_ERR("Invalid key length (%d)\n", key.len);
- return -EINVAL;
- }
-
- WL_CONN("Setting the key index %d\n", key.index);
- memcpy(key.data, params->key, key.len);
-
- if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
- u8 keybuf[8];
- memcpy(keybuf, &key.data[24], sizeof(keybuf));
- memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
- memcpy(&key.data[16], keybuf, sizeof(keybuf));
- }
-
- /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
- if (params->seq && params->seq_len == 6) {
- /* rx iv */
- u8 *ivptr;
- ivptr = (u8 *) params->seq;
- key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
- (ivptr[3] << 8) | ivptr[2];
- key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
- key.iv_initialized = true;
- }
-
- switch (params->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- key.algo = CRYPTO_ALGO_WEP1;
- WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- key.algo = CRYPTO_ALGO_WEP128;
- WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- key.algo = CRYPTO_ALGO_TKIP;
- WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
- break;
- case WLAN_CIPHER_SUITE_AES_CMAC:
- key.algo = CRYPTO_ALGO_AES_CCM;
- WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- key.algo = CRYPTO_ALGO_AES_CCM;
- WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
- break;
- default:
- WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
- return -EINVAL;
- }
- convert_key_from_CPU(&key, &key_le);
-
- brcmf_netdev_wait_pend8021x(ndev);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
- sizeof(key_le));
- if (err) {
- WL_ERR("WLC_SET_KEY error (%d)\n", err);
- return err;
- }
- }
- return err;
-}
-
-static s32
-brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_idx, bool pairwise, const u8 *mac_addr,
- struct key_params *params)
-{
- struct brcmf_wsec_key key;
- s32 val;
- s32 wsec;
- s32 err = 0;
- u8 keybuf[8];
-
- WL_TRACE("Enter\n");
- WL_CONN("key index (%d)\n", key_idx);
- if (!check_sys_up(wiphy))
- return -EIO;
-
- if (mac_addr) {
- WL_TRACE("Exit");
- return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
- }
- memset(&key, 0, sizeof(key));
-
- key.len = (u32) params->key_len;
- key.index = (u32) key_idx;
-
- if (key.len > sizeof(key.data)) {
- WL_ERR("Too long key length (%u)\n", key.len);
- err = -EINVAL;
- goto done;
- }
- memcpy(key.data, params->key, key.len);
-
- key.flags = BRCMF_PRIMARY_KEY;
- switch (params->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- key.algo = CRYPTO_ALGO_WEP1;
- WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- key.algo = CRYPTO_ALGO_WEP128;
- WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- memcpy(keybuf, &key.data[24], sizeof(keybuf));
- memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
- memcpy(&key.data[16], keybuf, sizeof(keybuf));
- key.algo = CRYPTO_ALGO_TKIP;
- WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
- break;
- case WLAN_CIPHER_SUITE_AES_CMAC:
- key.algo = CRYPTO_ALGO_AES_CCM;
- WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- key.algo = CRYPTO_ALGO_AES_CCM;
- WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
- break;
- default:
- WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
- err = -EINVAL;
- goto done;
- }
-
- err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
- if (err)
- goto done;
-
- val = WEP_ENABLED;
- err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
- if (err) {
- WL_ERR("get wsec error (%d)\n", err);
- goto done;
- }
- wsec &= ~(WEP_ENABLED);
- wsec |= val;
- err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
- if (err) {
- WL_ERR("set wsec error (%d)\n", err);
- goto done;
- }
-
- val = 1; /* assume shared key. otherwise 0 */
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
- if (err)
- WL_ERR("WLC_SET_AUTH error (%d)\n", err);
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_idx, bool pairwise, const u8 *mac_addr)
-{
- struct brcmf_wsec_key key;
- s32 err = 0;
- s32 val;
- s32 wsec;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- memset(&key, 0, sizeof(key));
-
- key.index = (u32) key_idx;
- key.flags = BRCMF_PRIMARY_KEY;
- key.algo = CRYPTO_ALGO_OFF;
-
- WL_CONN("key index (%d)\n", key_idx);
-
- /* Set the new key/index */
- err = send_key_to_dongle(ndev, &key);
- if (err) {
- if (err == -EINVAL) {
- if (key.index >= DOT11_MAX_DEFAULT_KEYS)
- /* we ignore this key index in this case */
- WL_ERR("invalid key index (%d)\n", key_idx);
- }
- /* Ignore this error, may happen during DISASSOC */
- err = -EAGAIN;
- goto done;
- }
-
- val = 0;
- err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
- if (err) {
- WL_ERR("get wsec error (%d)\n", err);
- /* Ignore this error, may happen during DISASSOC */
- err = -EAGAIN;
- goto done;
- }
- wsec &= ~(WEP_ENABLED);
- wsec |= val;
- err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
- if (err) {
- WL_ERR("set wsec error (%d)\n", err);
- /* Ignore this error, may happen during DISASSOC */
- err = -EAGAIN;
- goto done;
- }
-
- val = 0; /* assume open key. otherwise 1 */
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
- if (err) {
- WL_ERR("WLC_SET_AUTH error (%d)\n", err);
- /* Ignore this error, may happen during DISASSOC */
- err = -EAGAIN;
- }
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
- void (*callback) (void *cookie, struct key_params * params))
-{
- struct key_params params;
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct brcmf_cfg80211_security *sec;
- s32 wsec;
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- WL_CONN("key index (%d)\n", key_idx);
- if (!check_sys_up(wiphy))
- return -EIO;
-
- memset(&params, 0, sizeof(params));
-
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
- if (err) {
- WL_ERR("WLC_GET_WSEC error (%d)\n", err);
- /* Ignore this error, may happen during DISASSOC */
- err = -EAGAIN;
- goto done;
- }
- switch (wsec) {
- case WEP_ENABLED:
- sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
- if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
- params.cipher = WLAN_CIPHER_SUITE_WEP40;
- WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
- } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
- params.cipher = WLAN_CIPHER_SUITE_WEP104;
- WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
- }
- break;
- case TKIP_ENABLED:
- params.cipher = WLAN_CIPHER_SUITE_TKIP;
- WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
- break;
- case AES_ENABLED:
- params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
- WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
- break;
- default:
- WL_ERR("Invalid algo (0x%x)\n", wsec);
- err = -EINVAL;
- goto done;
- }
- callback(cookie, &params);
-
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
- struct net_device *ndev, u8 key_idx)
-{
- WL_INFO("Not supported\n");
-
- return -EOPNOTSUPP;
-}
-
-static s32
-brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
- u8 *mac, struct station_info *sinfo)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct brcmf_scb_val_le scb_val;
- int rssi;
- s32 rate;
- s32 err = 0;
- u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- if (memcmp(mac, bssid, ETH_ALEN)) {
- WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
- "wl_bssid-%X:%X:%X:%X:%X:%X\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
- bssid[0], bssid[1], bssid[2], bssid[3],
- bssid[4], bssid[5]);
- err = -ENOENT;
- goto done;
- }
-
- /* Report the current tx rate */
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
- if (err) {
- WL_ERR("Could not get rate (%d)\n", err);
- } else {
- sinfo->filled |= STATION_INFO_TX_BITRATE;
- sinfo->txrate.legacy = rate * 5;
- WL_CONN("Rate %d Mbps\n", rate / 2);
- }
-
- if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
- scb_val.val = cpu_to_le32(0);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
- sizeof(struct brcmf_scb_val_le));
- if (err)
- WL_ERR("Could not get rssi (%d)\n", err);
-
- rssi = le32_to_cpu(scb_val.val);
- sinfo->filled |= STATION_INFO_SIGNAL;
- sinfo->signal = rssi;
- WL_CONN("RSSI %d dBm\n", rssi);
- }
-
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
- bool enabled, s32 timeout)
-{
- s32 pm;
- s32 err = 0;
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
-
- WL_TRACE("Enter\n");
-
- /*
- * Powersave enable/disable request is coming from the
- * cfg80211 even before the interface is up. In that
- * scenario, driver will be storing the power save
- * preference in cfg_priv struct to apply this to
- * FW later while initializing the dongle
- */
- cfg_priv->pwr_save = enabled;
- if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
-
- WL_INFO("Device is not ready,"
- "storing the value in cfg_priv struct\n");
- goto done;
- }
-
- pm = enabled ? PM_FAST : PM_OFF;
- WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
-
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
- if (err) {
- if (err == -ENODEV)
- WL_ERR("net_device is not ready yet\n");
- else
- WL_ERR("error (%d)\n", err);
- }
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
- const u8 *addr,
- const struct cfg80211_bitrate_mask *mask)
-{
- struct brcm_rateset_le rateset_le;
- s32 rate;
- s32 val;
- s32 err_bg;
- s32 err_a;
- u32 legacy;
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- /* addr param is always NULL. ignore it */
- /* Get current rateset */
- err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
- sizeof(rateset_le));
- if (err) {
- WL_ERR("could not get current rateset (%d)\n", err);
- goto done;
- }
-
- legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
- if (!legacy)
- legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
- 0xFFFF);
-
- val = wl_g_rates[legacy - 1].bitrate * 100000;
-
- if (val < le32_to_cpu(rateset_le.count))
- /* Select rate by rateset index */
- rate = rateset_le.rates[val] & 0x7f;
- else
- /* Specified rate in bps */
- rate = val / 500000;
-
- WL_CONN("rate %d mbps\n", rate / 2);
-
- /*
- *
- * Set rate override,
- * Since the is a/b/g-blind, both a/bg_rate are enforced.
- */
- err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
- err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
- if (err_bg && err_a) {
- WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
- err = err_bg | err_a;
- }
-
-done:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
- struct brcmf_bss_info *bi)
-{
- struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
- struct ieee80211_channel *notify_channel;
- struct cfg80211_bss *bss;
- struct ieee80211_supported_band *band;
- s32 err = 0;
- u16 channel;
- u32 freq;
- u64 notify_timestamp;
- u16 notify_capability;
- u16 notify_interval;
- u8 *notify_ie;
- size_t notify_ielen;
- s32 notify_signal;
-
- if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
- WL_ERR("Bss info is larger than buffer. Discarding\n");
- return 0;
- }
-
- channel = bi->ctl_ch ? bi->ctl_ch :
- CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
-
- if (channel <= CH_MAX_2G_CHANNEL)
- band = wiphy->bands[IEEE80211_BAND_2GHZ];
- else
- band = wiphy->bands[IEEE80211_BAND_5GHZ];
-
- freq = ieee80211_channel_to_frequency(channel, band->band);
- notify_channel = ieee80211_get_channel(wiphy, freq);
-
- notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
- notify_capability = le16_to_cpu(bi->capability);
- notify_interval = le16_to_cpu(bi->beacon_period);
- notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
- notify_ielen = le32_to_cpu(bi->ie_length);
- notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
-
- WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
- bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
- bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
- WL_CONN("Channel: %d(%d)\n", channel, freq);
- WL_CONN("Capability: %X\n", notify_capability);
- WL_CONN("Beacon interval: %d\n", notify_interval);
- WL_CONN("Signal: %d\n", notify_signal);
- WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
-
- bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
- notify_timestamp, notify_capability, notify_interval, notify_ie,
- notify_ielen, notify_signal, GFP_KERNEL);
-
- if (!bss) {
- WL_ERR("cfg80211_inform_bss_frame error\n");
- return -EINVAL;
- }
-
- return err;
-}
-
-static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_scan_results *bss_list;
- struct brcmf_bss_info *bi = NULL; /* must be initialized */
- s32 err = 0;
- int i;
-
- bss_list = cfg_priv->bss_list;
- if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
- WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
- bss_list->version);
- return -EOPNOTSUPP;
- }
- WL_SCAN("scanned AP count (%d)\n", bss_list->count);
- for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
- bi = next_bss(bss_list, bi);
- err = brcmf_inform_single_bss(cfg_priv, bi);
- if (err)
- break;
- }
- return err;
-}
-
-static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
- struct net_device *ndev, const u8 *bssid)
-{
- struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
- struct ieee80211_channel *notify_channel;
- struct brcmf_bss_info *bi = NULL;
- struct ieee80211_supported_band *band;
- u8 *buf = NULL;
- s32 err = 0;
- u16 channel;
- u32 freq;
- u64 notify_timestamp;
- u16 notify_capability;
- u16 notify_interval;
- u8 *notify_ie;
- size_t notify_ielen;
- s32 notify_signal;
-
- WL_TRACE("Enter\n");
-
- buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
- if (buf == NULL) {
- err = -ENOMEM;
- goto CleanUp;
- }
-
- *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
-
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
- if (err) {
- WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
- goto CleanUp;
- }
-
- bi = (struct brcmf_bss_info *)(buf + 4);
-
- channel = bi->ctl_ch ? bi->ctl_ch :
- CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
-
- if (channel <= CH_MAX_2G_CHANNEL)
- band = wiphy->bands[IEEE80211_BAND_2GHZ];
- else
- band = wiphy->bands[IEEE80211_BAND_5GHZ];
-
- freq = ieee80211_channel_to_frequency(channel, band->band);
- notify_channel = ieee80211_get_channel(wiphy, freq);
-
- notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
- notify_capability = le16_to_cpu(bi->capability);
- notify_interval = le16_to_cpu(bi->beacon_period);
- notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
- notify_ielen = le32_to_cpu(bi->ie_length);
- notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
-
- WL_CONN("channel: %d(%d)\n", channel, freq);
- WL_CONN("capability: %X\n", notify_capability);
- WL_CONN("beacon interval: %d\n", notify_interval);
- WL_CONN("signal: %d\n", notify_signal);
- WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
-
- cfg80211_inform_bss(wiphy, notify_channel, bssid,
- notify_timestamp, notify_capability, notify_interval,
- notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
-
-CleanUp:
-
- kfree(buf);
-
- WL_TRACE("Exit\n");
-
- return err;
-}
-
-static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
-{
- return cfg_priv->conf->mode == WL_MODE_IBSS;
-}
-
-static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_bss_info *bi;
- struct brcmf_ssid *ssid;
- struct brcmu_tlv *tim;
- u16 beacon_interval;
- u8 dtim_period;
- size_t ie_len;
- u8 *ie;
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- if (brcmf_is_ibssmode(cfg_priv))
- return err;
-
- ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
-
- *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
- err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
- cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
- if (err) {
- WL_ERR("Could not get bss info %d\n", err);
- goto update_bss_info_out;
- }
-
- bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
- err = brcmf_inform_single_bss(cfg_priv, bi);
- if (err)
- goto update_bss_info_out;
-
- ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
- ie_len = le32_to_cpu(bi->ie_length);
- beacon_interval = le16_to_cpu(bi->beacon_period);
-
- tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
- if (tim)
- dtim_period = tim->data[1];
- else {
- /*
- * active scan was done so we could not get dtim
- * information out of probe response.
- * so we speficially query dtim information to dongle.
- */
- u32 var;
- err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
- "dtim_assoc", &var);
- if (err) {
- WL_ERR("wl dtim_assoc failed (%d)\n", err);
- goto update_bss_info_out;
- }
- dtim_period = (u8)var;
- }
-
- brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
- brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
-
-update_bss_info_out:
- WL_TRACE("Exit");
- return err;
-}
-
-static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
- struct brcmf_ssid ssid;
-
- if (cfg_priv->iscan_on) {
- iscan->state = WL_ISCAN_STATE_IDLE;
-
- if (iscan->timer_on) {
- del_timer_sync(&iscan->timer);
- iscan->timer_on = 0;
- }
-
- cancel_work_sync(&iscan->work);
-
- /* Abort iscan running in FW */
- memset(&ssid, 0, sizeof(ssid));
- brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
- }
-}
-
-static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
- bool aborted)
-{
- struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
- struct net_device *ndev = cfg_to_ndev(cfg_priv);
-
- if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
- WL_ERR("Scan complete while device not scanning\n");
- return;
- }
- if (cfg_priv->scan_request) {
- WL_SCAN("ISCAN Completed scan: %s\n",
- aborted ? "Aborted" : "Done");
- cfg80211_scan_done(cfg_priv->scan_request, aborted);
- brcmf_set_mpc(ndev, 1);
- cfg_priv->scan_request = NULL;
- }
- cfg_priv->iscan_kickstart = false;
-}
-
-static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
-{
- if (iscan->state != WL_ISCAN_STATE_IDLE) {
- WL_SCAN("wake up iscan\n");
- schedule_work(&iscan->work);
- return 0;
- }
-
- return -EIO;
-}
-
-static s32
-brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
- struct brcmf_scan_results **bss_list)
-{
- struct brcmf_iscan_results list;
- struct brcmf_scan_results *results;
- struct brcmf_scan_results_le *results_le;
- struct brcmf_iscan_results *list_buf;
- s32 err = 0;
-
- memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
- list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
- results = &list_buf->results;
- results_le = &list_buf->results_le;
- results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
- results->version = 0;
- results->count = 0;
-
- memset(&list, 0, sizeof(list));
- list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
- err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
- BRCMF_ISCAN_RESULTS_FIXED_SIZE,
- iscan->scan_buf, WL_ISCAN_BUF_MAX);
- if (err) {
- WL_ERR("error (%d)\n", err);
- return err;
- }
- results->buflen = le32_to_cpu(results_le->buflen);
- results->version = le32_to_cpu(results_le->version);
- results->count = le32_to_cpu(results_le->count);
- WL_SCAN("results->count = %d\n", results_le->count);
- WL_SCAN("results->buflen = %d\n", results_le->buflen);
- *status = le32_to_cpu(list_buf->status_le);
- WL_SCAN("status = %d\n", *status);
- *bss_list = results;
-
- return err;
-}
-
-static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
- s32 err = 0;
-
- iscan->state = WL_ISCAN_STATE_IDLE;
- brcmf_inform_bss(cfg_priv);
- brcmf_notify_iscan_complete(iscan, false);
-
- return err;
-}
-
-static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
- s32 err = 0;
-
- /* Reschedule the timer */
- mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
- iscan->timer_on = 1;
-
- return err;
-}
-
-static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
- s32 err = 0;
-
- brcmf_inform_bss(cfg_priv);
- brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
- /* Reschedule the timer */
- mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
- iscan->timer_on = 1;
-
- return err;
-}
-
-static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
- s32 err = 0;
-
- iscan->state = WL_ISCAN_STATE_IDLE;
- brcmf_notify_iscan_complete(iscan, true);
-
- return err;
-}
-
-static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan =
- container_of(work, struct brcmf_cfg80211_iscan_ctrl,
- work);
- struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
- struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
- u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
-
- if (iscan->timer_on) {
- del_timer_sync(&iscan->timer);
- iscan->timer_on = 0;
- }
-
- if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
- status = BRCMF_SCAN_RESULTS_ABORTED;
- WL_ERR("Abort iscan\n");
- }
-
- el->handler[status](cfg_priv);
-}
-
-static void brcmf_iscan_timer(unsigned long data)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan =
- (struct brcmf_cfg80211_iscan_ctrl *)data;
-
- if (iscan) {
- iscan->timer_on = 0;
- WL_SCAN("timer expired\n");
- brcmf_wakeup_iscan(iscan);
- }
-}
-
-static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
-
- if (cfg_priv->iscan_on) {
- iscan->state = WL_ISCAN_STATE_IDLE;
- INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
- }
-
- return 0;
-}
-
-static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
-{
- memset(el, 0, sizeof(*el));
- el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
- el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
- el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
- el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
- el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
-}
-
-static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
- int err = 0;
-
- if (cfg_priv->iscan_on) {
- iscan->ndev = cfg_to_ndev(cfg_priv);
- brcmf_init_iscan_eloop(&iscan->el);
- iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
- init_timer(&iscan->timer);
- iscan->timer.data = (unsigned long) iscan;
- iscan->timer.function = brcmf_iscan_timer;
- err = brcmf_invoke_iscan(cfg_priv);
- if (!err)
- iscan->data = cfg_priv;
- }
-
- return err;
-}
-
-static void brcmf_delay(u32 ms)
-{
- if (ms < 1000 / HZ) {
- cond_resched();
- mdelay(ms);
- } else {
- msleep(ms);
- }
-}
-
-static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
-
- /*
- * Check for WL_STATUS_READY before any function call which
- * could result is bus access. Don't block the resume for
- * any driver error conditions
- */
- WL_TRACE("Enter\n");
-
- if (test_bit(WL_STATUS_READY, &cfg_priv->status))
- brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
-
- WL_TRACE("Exit\n");
- return 0;
-}
-
-static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
- struct cfg80211_wowlan *wow)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct net_device *ndev = cfg_to_ndev(cfg_priv);
-
- WL_TRACE("Enter\n");
-
- /*
- * Check for WL_STATUS_READY before any function call which
- * could result is bus access. Don't block the suspend for
- * any driver error conditions
- */
-
- /*
- * While going to suspend if associated with AP disassociate
- * from AP to save power while system is in suspended state
- */
- if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
- test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
- test_bit(WL_STATUS_READY, &cfg_priv->status)) {
- WL_INFO("Disassociating from AP"
- " while entering suspend state\n");
- brcmf_link_down(cfg_priv);
-
- /*
- * Make sure WPA_Supplicant receives all the event
- * generated due to DISASSOC call to the fw to keep
- * the state fw and WPA_Supplicant state consistent
- */
- brcmf_delay(500);
- }
-
- set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
- if (test_bit(WL_STATUS_READY, &cfg_priv->status))
- brcmf_term_iscan(cfg_priv);
-
- if (cfg_priv->scan_request) {
- /* Indidate scan abort to cfg80211 layer */
- WL_INFO("Terminating scan in progress\n");
- cfg80211_scan_done(cfg_priv->scan_request, true);
- cfg_priv->scan_request = NULL;
- }
- clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
- clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
-
- /* Turn off watchdog timer */
- if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
- WL_INFO("Enable MPC\n");
- brcmf_set_mpc(ndev, 1);
- }
-
- WL_TRACE("Exit\n");
-
- return 0;
-}
-
-static __used s32
-brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
-{
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
- u32 buflen;
-
- buflen = brcmu_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
- WL_DCMD_LEN_MAX);
- BUG_ON(!buflen);
-
- return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
- buflen);
-}
-
-static s32
-brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
- s32 buf_len)
-{
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
- u32 len;
- s32 err = 0;
-
- len = brcmu_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
- WL_DCMD_LEN_MAX);
- BUG_ON(!len);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
- WL_DCMD_LEN_MAX);
- if (err) {
- WL_ERR("error (%d)\n", err);
- return err;
- }
- memcpy(buf, cfg_priv->dcmd_buf, buf_len);
-
- return err;
-}
-
-static __used s32
-brcmf_update_pmklist(struct net_device *ndev,
- struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
-{
- int i, j;
-
- WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
- for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
- WL_CONN("PMKID[%d]: %pM =\n", i,
- &pmk_list->pmkids.pmkid[i].BSSID);
- for (j = 0; j < WLAN_PMKID_LEN; j++)
- WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
- }
-
- if (!err)
- brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
- sizeof(*pmk_list));
-
- return err;
-}
-
-static s32
-brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_pmksa *pmksa)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
- s32 err = 0;
- int i;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- for (i = 0; i < pmkids->npmkid; i++)
- if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
- break;
- if (i < WL_NUM_PMKIDS_MAX) {
- memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
- memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
- if (i == pmkids->npmkid)
- pmkids->npmkid++;
- } else
- err = -EINVAL;
-
- WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
- pmkids->pmkid[pmkids->npmkid].BSSID);
- for (i = 0; i < WLAN_PMKID_LEN; i++)
- WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
-
- err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
-
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_pmksa *pmksa)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- struct pmkid_list pmkid;
- s32 err = 0;
- int i;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
- memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
-
- WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
- &pmkid.pmkid[0].BSSID);
- for (i = 0; i < WLAN_PMKID_LEN; i++)
- WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
-
- for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
- if (!memcmp
- (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
- ETH_ALEN))
- break;
-
- if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
- && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
- memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
- sizeof(struct pmkid));
- for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
- memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
- &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
- ETH_ALEN);
- memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
- &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
- WLAN_PMKID_LEN);
- }
- cfg_priv->pmk_list->pmkids.npmkid--;
- } else
- err = -EINVAL;
-
- err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
-
- WL_TRACE("Exit\n");
- return err;
-
-}
-
-static s32
-brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
-{
- struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
- s32 err = 0;
-
- WL_TRACE("Enter\n");
- if (!check_sys_up(wiphy))
- return -EIO;
-
- memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
- err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
-
- WL_TRACE("Exit\n");
- return err;
-
-}
-
-static struct cfg80211_ops wl_cfg80211_ops = {
- .change_virtual_intf = brcmf_cfg80211_change_iface,
- .scan = brcmf_cfg80211_scan,
- .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
- .join_ibss = brcmf_cfg80211_join_ibss,
- .leave_ibss = brcmf_cfg80211_leave_ibss,
- .get_station = brcmf_cfg80211_get_station,
- .set_tx_power = brcmf_cfg80211_set_tx_power,
- .get_tx_power = brcmf_cfg80211_get_tx_power,
- .add_key = brcmf_cfg80211_add_key,
- .del_key = brcmf_cfg80211_del_key,
- .get_key = brcmf_cfg80211_get_key,
- .set_default_key = brcmf_cfg80211_config_default_key,
- .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
- .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
- .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
- .connect = brcmf_cfg80211_connect,
- .disconnect = brcmf_cfg80211_disconnect,
- .suspend = brcmf_cfg80211_suspend,
- .resume = brcmf_cfg80211_resume,
- .set_pmksa = brcmf_cfg80211_set_pmksa,
- .del_pmksa = brcmf_cfg80211_del_pmksa,
- .flush_pmksa = brcmf_cfg80211_flush_pmksa
-};
-
-static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
-{
- s32 err = 0;
-
- switch (mode) {
- case WL_MODE_BSS:
- return NL80211_IFTYPE_STATION;
- case WL_MODE_IBSS:
- return NL80211_IFTYPE_ADHOC;
- default:
- return NL80211_IFTYPE_UNSPECIFIED;
- }
-
- return err;
-}
-
-static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
- struct device *ndev)
-{
- struct wireless_dev *wdev;
- s32 err = 0;
-
- wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
- if (!wdev)
- return ERR_PTR(-ENOMEM);
-
- wdev->wiphy =
- wiphy_new(&wl_cfg80211_ops,
- sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
- if (!wdev->wiphy) {
- WL_ERR("Couldn not allocate wiphy device\n");
- err = -ENOMEM;
- goto wiphy_new_out;
- }
- set_wiphy_dev(wdev->wiphy, ndev);
- wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
- wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
- wdev->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
- wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
- wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
- * it as 11a by default.
- * This will be updated with
- * 11n phy tables in
- * "ifconfig up"
- * if phy has 11n capability
- */
- wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
- wdev->wiphy->cipher_suites = __wl_cipher_suites;
- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
- wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
- * save mode
- * by default
- */
- err = wiphy_register(wdev->wiphy);
- if (err < 0) {
- WL_ERR("Couldn not register wiphy device (%d)\n", err);
- goto wiphy_register_out;
- }
- return wdev;
-
-wiphy_register_out:
- wiphy_free(wdev->wiphy);
-
-wiphy_new_out:
- kfree(wdev);
-
- return ERR_PTR(err);
-}
-
-static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct wireless_dev *wdev = cfg_priv->wdev;
-
- if (!wdev) {
- WL_ERR("wdev is invalid\n");
- return;
- }
- wiphy_unregister(wdev->wiphy);
- wiphy_free(wdev->wiphy);
- kfree(wdev);
- cfg_priv->wdev = NULL;
-}
-
-static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
- const struct brcmf_event_msg *e)
-{
- u32 event = be32_to_cpu(e->event_type);
- u32 status = be32_to_cpu(e->status);
-
- if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
- WL_CONN("Processing set ssid\n");
- cfg_priv->link_up = true;
- return true;
- }
-
- return false;
-}
-
-static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
- const struct brcmf_event_msg *e)
-{
- u32 event = be32_to_cpu(e->event_type);
- u16 flags = be16_to_cpu(e->flags);
-
- if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
- WL_CONN("Processing link down\n");
- return true;
- }
- return false;
-}
-
-static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
- const struct brcmf_event_msg *e)
-{
- u32 event = be32_to_cpu(e->event_type);
- u32 status = be32_to_cpu(e->status);
-
- if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
- WL_CONN("Processing Link %s & no network found\n",
- be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
- "up" : "down");
- return true;
- }
-
- if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
- WL_CONN("Processing connecting & no network found\n");
- return true;
- }
-
- return false;
-}
-
-static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
-
- kfree(conn_info->req_ie);
- conn_info->req_ie = NULL;
- conn_info->req_ie_len = 0;
- kfree(conn_info->resp_ie);
- conn_info->resp_ie = NULL;
- conn_info->resp_ie_len = 0;
-}
-
-static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct net_device *ndev = cfg_to_ndev(cfg_priv);
- struct brcmf_cfg80211_assoc_ielen *assoc_info;
- struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
- u32 req_len;
- u32 resp_len;
- s32 err = 0;
-
- brcmf_clear_assoc_ies(cfg_priv);
-
- err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
- WL_ASSOC_INFO_MAX);
- if (err) {
- WL_ERR("could not get assoc info (%d)\n", err);
- return err;
- }
- assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
- req_len = assoc_info->req_len;
- resp_len = assoc_info->resp_len;
- if (req_len) {
- err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
- cfg_priv->extra_buf,
- WL_ASSOC_INFO_MAX);
- if (err) {
- WL_ERR("could not get assoc req (%d)\n", err);
- return err;
- }
- conn_info->req_ie_len = req_len;
- conn_info->req_ie =
- kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
- GFP_KERNEL);
- } else {
- conn_info->req_ie_len = 0;
- conn_info->req_ie = NULL;
- }
- if (resp_len) {
- err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
- cfg_priv->extra_buf,
- WL_ASSOC_INFO_MAX);
- if (err) {
- WL_ERR("could not get assoc resp (%d)\n", err);
- return err;
- }
- conn_info->resp_ie_len = resp_len;
- conn_info->resp_ie =
- kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
- GFP_KERNEL);
- } else {
- conn_info->resp_ie_len = 0;
- conn_info->resp_ie = NULL;
- }
- WL_CONN("req len (%d) resp len (%d)\n",
- conn_info->req_ie_len, conn_info->resp_ie_len);
-
- return err;
-}
-
-static s32
-brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
- struct net_device *ndev,
- const struct brcmf_event_msg *e)
-{
- struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
- struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
- struct brcmf_channel_info_le channel_le;
- struct ieee80211_channel *notify_channel;
- struct ieee80211_supported_band *band;
- u32 freq;
- s32 err = 0;
- u32 target_channel;
-
- WL_TRACE("Enter\n");
-
- brcmf_get_assoc_ies(cfg_priv);
- brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
- brcmf_update_bss_info(cfg_priv);
-
- brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
- sizeof(channel_le));
-
- target_channel = le32_to_cpu(channel_le.target_channel);
- WL_CONN("Roamed to channel %d\n", target_channel);
-
- if (target_channel <= CH_MAX_2G_CHANNEL)
- band = wiphy->bands[IEEE80211_BAND_2GHZ];
- else
- band = wiphy->bands[IEEE80211_BAND_5GHZ];
-
- freq = ieee80211_channel_to_frequency(target_channel, band->band);
- notify_channel = ieee80211_get_channel(wiphy, freq);
-
- cfg80211_roamed(ndev, notify_channel,
- (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
- conn_info->req_ie, conn_info->req_ie_len,
- conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
- WL_CONN("Report roaming result\n");
-
- set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
- struct net_device *ndev, const struct brcmf_event_msg *e,
- bool completed)
-{
- struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
- s32 err = 0;
-
- WL_TRACE("Enter\n");
-
- if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
- if (completed) {
- brcmf_get_assoc_ies(cfg_priv);
- brcmf_update_prof(cfg_priv, NULL, &e->addr,
- WL_PROF_BSSID);
- brcmf_update_bss_info(cfg_priv);
- }
- cfg80211_connect_result(ndev,
- (u8 *)brcmf_read_prof(cfg_priv,
- WL_PROF_BSSID),
- conn_info->req_ie,
- conn_info->req_ie_len,
- conn_info->resp_ie,
- conn_info->resp_ie_len,
- completed ? WLAN_STATUS_SUCCESS :
- WLAN_STATUS_AUTH_TIMEOUT,
- GFP_KERNEL);
- if (completed)
- set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
- WL_CONN("Report connect result - connection %s\n",
- completed ? "succeeded" : "failed");
- }
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
- struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data)
-{
- s32 err = 0;
-
- if (brcmf_is_linkup(cfg_priv, e)) {
- WL_CONN("Linkup\n");
- if (brcmf_is_ibssmode(cfg_priv)) {
- brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
- WL_PROF_BSSID);
- wl_inform_ibss(cfg_priv, ndev, e->addr);
- cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
- clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
- set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
- } else
- brcmf_bss_connect_done(cfg_priv, ndev, e, true);
- } else if (brcmf_is_linkdown(cfg_priv, e)) {
- WL_CONN("Linkdown\n");
- if (brcmf_is_ibssmode(cfg_priv)) {
- clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
- if (test_and_clear_bit(WL_STATUS_CONNECTED,
- &cfg_priv->status))
- brcmf_link_down(cfg_priv);
- } else {
- brcmf_bss_connect_done(cfg_priv, ndev, e, false);
- if (test_and_clear_bit(WL_STATUS_CONNECTED,
- &cfg_priv->status)) {
- cfg80211_disconnected(ndev, 0, NULL, 0,
- GFP_KERNEL);
- brcmf_link_down(cfg_priv);
- }
- }
- brcmf_init_prof(cfg_priv->profile);
- } else if (brcmf_is_nonetwork(cfg_priv, e)) {
- if (brcmf_is_ibssmode(cfg_priv))
- clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
- else
- brcmf_bss_connect_done(cfg_priv, ndev, e, false);
- }
-
- return err;
-}
-
-static s32
-brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
- struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data)
-{
- s32 err = 0;
- u32 event = be32_to_cpu(e->event_type);
- u32 status = be32_to_cpu(e->status);
-
- if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
- if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
- brcmf_bss_roaming_done(cfg_priv, ndev, e);
- else
- brcmf_bss_connect_done(cfg_priv, ndev, e, true);
- }
-
- return err;
-}
-
-static s32
-brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
- struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data)
-{
- u16 flags = be16_to_cpu(e->flags);
- enum nl80211_key_type key_type;
-
- if (flags & BRCMF_EVENT_MSG_GROUP)
- key_type = NL80211_KEYTYPE_GROUP;
- else
- key_type = NL80211_KEYTYPE_PAIRWISE;
-
- cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
- NULL, GFP_KERNEL);
-
- return 0;
-}
-
-static s32
-brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
- struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data)
-{
- struct brcmf_channel_info_le channel_inform_le;
- struct brcmf_scan_results_le *bss_list_le;
- u32 len = WL_SCAN_BUF_MAX;
- s32 err = 0;
- bool scan_abort = false;
- u32 scan_channel;
-
- WL_TRACE("Enter\n");
-
- if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
- WL_TRACE("Exit\n");
- return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
- }
-
- if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
- WL_ERR("Scan complete while device not scanning\n");
- scan_abort = true;
- err = -EINVAL;
- goto scan_done_out;
- }
-
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
- sizeof(channel_inform_le));
- if (err) {
- WL_ERR("scan busy (%d)\n", err);
- scan_abort = true;
- goto scan_done_out;
- }
- scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
- if (scan_channel)
- WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
- cfg_priv->bss_list = cfg_priv->scan_results;
- bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
-
- memset(cfg_priv->scan_results, 0, len);
- bss_list_le->buflen = cpu_to_le32(len);
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
- cfg_priv->scan_results, len);
- if (err) {
- WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
- err = -EINVAL;
- scan_abort = true;
- goto scan_done_out;
- }
- cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
- cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
- cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
-
- err = brcmf_inform_bss(cfg_priv);
- if (err) {
- scan_abort = true;
- goto scan_done_out;
- }
-
-scan_done_out:
- if (cfg_priv->scan_request) {
- WL_SCAN("calling cfg80211_scan_done\n");
- cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
- brcmf_set_mpc(ndev, 1);
- cfg_priv->scan_request = NULL;
- }
-
- WL_TRACE("Exit\n");
-
- return err;
-}
-
-static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
-{
- conf->mode = (u32)-1;
- conf->frag_threshold = (u32)-1;
- conf->rts_threshold = (u32)-1;
- conf->retry_short = (u32)-1;
- conf->retry_long = (u32)-1;
- conf->tx_power = -1;
-}
-
-static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
-{
- memset(el, 0, sizeof(*el));
- el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
- el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
- el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
- el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
- el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
-}
-
-static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
-{
- kfree(cfg_priv->scan_results);
- cfg_priv->scan_results = NULL;
- kfree(cfg_priv->bss_info);
- cfg_priv->bss_info = NULL;
- kfree(cfg_priv->conf);
- cfg_priv->conf = NULL;
- kfree(cfg_priv->profile);
- cfg_priv->profile = NULL;
- kfree(cfg_priv->scan_req_int);
- cfg_priv->scan_req_int = NULL;
- kfree(cfg_priv->dcmd_buf);
- cfg_priv->dcmd_buf = NULL;
- kfree(cfg_priv->extra_buf);
- cfg_priv->extra_buf = NULL;
- kfree(cfg_priv->iscan);
- cfg_priv->iscan = NULL;
- kfree(cfg_priv->pmk_list);
- cfg_priv->pmk_list = NULL;
-}
-
-static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
-{
- cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
- if (!cfg_priv->scan_results)
- goto init_priv_mem_out;
- cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
- if (!cfg_priv->conf)
- goto init_priv_mem_out;
- cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
- if (!cfg_priv->profile)
- goto init_priv_mem_out;
- cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
- if (!cfg_priv->bss_info)
- goto init_priv_mem_out;
- cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
- GFP_KERNEL);
- if (!cfg_priv->scan_req_int)
- goto init_priv_mem_out;
- cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
- if (!cfg_priv->dcmd_buf)
- goto init_priv_mem_out;
- cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
- if (!cfg_priv->extra_buf)
- goto init_priv_mem_out;
- cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
- if (!cfg_priv->iscan)
- goto init_priv_mem_out;
- cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
- if (!cfg_priv->pmk_list)
- goto init_priv_mem_out;
-
- return 0;
-
-init_priv_mem_out:
- brcmf_deinit_priv_mem(cfg_priv);
-
- return -ENOMEM;
-}
-
-/*
-* retrieve first queued event from head
-*/
-
-static struct brcmf_cfg80211_event_q *brcmf_deq_event(
- struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_event_q *e = NULL;
-
- spin_lock_irq(&cfg_priv->evt_q_lock);
- if (!list_empty(&cfg_priv->evt_q_list)) {
- e = list_first_entry(&cfg_priv->evt_q_list,
- struct brcmf_cfg80211_event_q, evt_q_list);
- list_del(&e->evt_q_list);
- }
- spin_unlock_irq(&cfg_priv->evt_q_lock);
-
- return e;
-}
-
-/*
-** push event to tail of the queue
-*/
-
-static s32
-brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
- const struct brcmf_event_msg *msg)
-{
- struct brcmf_cfg80211_event_q *e;
- s32 err = 0;
-
- e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
- if (!e)
- return -ENOMEM;
-
- e->etype = event;
- memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
-
- spin_lock_irq(&cfg_priv->evt_q_lock);
- list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
- spin_unlock_irq(&cfg_priv->evt_q_lock);
-
- return err;
-}
-
-static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
-{
- kfree(e);
-}
-
-static void brcmf_cfg80211_event_handler(struct work_struct *work)
-{
- struct brcmf_cfg80211_priv *cfg_priv =
- container_of(work, struct brcmf_cfg80211_priv,
- event_work);
- struct brcmf_cfg80211_event_q *e;
-
- e = brcmf_deq_event(cfg_priv);
- if (unlikely(!e)) {
- WL_ERR("event queue empty...\n");
- return;
- }
-
- do {
- WL_INFO("event type (%d)\n", e->etype);
- if (cfg_priv->el.handler[e->etype])
- cfg_priv->el.handler[e->etype](cfg_priv,
- cfg_to_ndev(cfg_priv),
- &e->emsg, e->edata);
- else
- WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
- brcmf_put_event(e);
- } while ((e = brcmf_deq_event(cfg_priv)));
-
-}
-
-static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
-{
- spin_lock_init(&cfg_priv->evt_q_lock);
- INIT_LIST_HEAD(&cfg_priv->evt_q_list);
-}
-
-static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct brcmf_cfg80211_event_q *e;
-
- spin_lock_irq(&cfg_priv->evt_q_lock);
- while (!list_empty(&cfg_priv->evt_q_list)) {
- e = list_first_entry(&cfg_priv->evt_q_list,
- struct brcmf_cfg80211_event_q, evt_q_list);
- list_del(&e->evt_q_list);
- kfree(e);
- }
- spin_unlock_irq(&cfg_priv->evt_q_lock);
-}
-
-static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
-{
- s32 err = 0;
-
- cfg_priv->scan_request = NULL;
- cfg_priv->pwr_save = true;
- cfg_priv->iscan_on = true; /* iscan on & off switch.
- we enable iscan per default */
- cfg_priv->roam_on = true; /* roam on & off switch.
- we enable roam per default */
-
- cfg_priv->iscan_kickstart = false;
- cfg_priv->active_scan = true; /* we do active scan for
- specific scan per default */
- cfg_priv->dongle_up = false; /* dongle is not up yet */
- brcmf_init_eq(cfg_priv);
- err = brcmf_init_priv_mem(cfg_priv);
- if (err)
- return err;
- INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
- brcmf_init_eloop_handler(&cfg_priv->el);
- mutex_init(&cfg_priv->usr_sync);
- err = brcmf_init_iscan(cfg_priv);
- if (err)
- return err;
- brcmf_init_conf(cfg_priv->conf);
- brcmf_init_prof(cfg_priv->profile);
- brcmf_link_down(cfg_priv);
-
- return err;
-}
-
-static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
-{
- cancel_work_sync(&cfg_priv->event_work);
- cfg_priv->dongle_up = false; /* dongle down */
- brcmf_flush_eq(cfg_priv);
- brcmf_link_down(cfg_priv);
- brcmf_term_iscan(cfg_priv);
- brcmf_deinit_priv_mem(cfg_priv);
-}
-
-struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
- struct device *busdev,
- void *data)
-{
- struct wireless_dev *wdev;
- struct brcmf_cfg80211_priv *cfg_priv;
- struct brcmf_cfg80211_iface *ci;
- struct brcmf_cfg80211_dev *cfg_dev;
- s32 err = 0;
-
- if (!ndev) {
- WL_ERR("ndev is invalid\n");
- return NULL;
- }
- cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
- if (!cfg_dev)
- return NULL;
-
- wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
- if (IS_ERR(wdev)) {
- kfree(cfg_dev);
- return NULL;
- }
-
- wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
- cfg_priv = wdev_to_cfg(wdev);
- cfg_priv->wdev = wdev;
- cfg_priv->pub = data;
- ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
- ci->cfg_priv = cfg_priv;
- ndev->ieee80211_ptr = wdev;
- SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
- wdev->netdev = ndev;
- err = wl_init_priv(cfg_priv);
- if (err) {
- WL_ERR("Failed to init iwm_priv (%d)\n", err);
- goto cfg80211_attach_out;
- }
- brcmf_set_drvdata(cfg_dev, ci);
-
- return cfg_dev;
-
-cfg80211_attach_out:
- brcmf_free_wdev(cfg_priv);
- kfree(cfg_dev);
- return NULL;
-}
-
-void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
-{
- struct brcmf_cfg80211_priv *cfg_priv;
-
- cfg_priv = brcmf_priv_get(cfg_dev);
-
- wl_deinit_priv(cfg_priv);
- brcmf_free_wdev(cfg_priv);
- brcmf_set_drvdata(cfg_dev, NULL);
- kfree(cfg_dev);
-}
-
-void
-brcmf_cfg80211_event(struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data)
-{
- u32 event_type = be32_to_cpu(e->event_type);
- struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
-
- if (!brcmf_enq_event(cfg_priv, event_type, e))
- schedule_work(&cfg_priv->event_work);
-}
-
-static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
-{
- s32 infra = 0;
- s32 err = 0;
-
- switch (iftype) {
- case NL80211_IFTYPE_MONITOR:
- case NL80211_IFTYPE_WDS:
- WL_ERR("type (%d) : currently we do not support this mode\n",
- iftype);
- err = -EINVAL;
- return err;
- case NL80211_IFTYPE_ADHOC:
- infra = 0;
- break;
- case NL80211_IFTYPE_STATION:
- infra = 1;
- break;
- default:
- err = -EINVAL;
- WL_ERR("invalid type (%d)\n", iftype);
- return err;
- }
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
- if (err) {
- WL_ERR("WLC_SET_INFRA error (%d)\n", err);
- return err;
- }
-
- return 0;
-}
-
-static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
-{
- /* Room for "event_msgs" + '\0' + bitvec */
- s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
- s8 eventmask[BRCMF_EVENTING_MASK_LEN];
- s32 err = 0;
-
- WL_TRACE("Enter\n");
-
- /* Setup event_msgs */
- brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
- sizeof(iovbuf));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
- if (err) {
- WL_ERR("Get event_msgs error (%d)\n", err);
- goto dongle_eventmsg_out;
- }
- memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
-
- setbit(eventmask, BRCMF_E_SET_SSID);
- setbit(eventmask, BRCMF_E_ROAM);
- setbit(eventmask, BRCMF_E_PRUNE);
- setbit(eventmask, BRCMF_E_AUTH);
- setbit(eventmask, BRCMF_E_REASSOC);
- setbit(eventmask, BRCMF_E_REASSOC_IND);
- setbit(eventmask, BRCMF_E_DEAUTH_IND);
- setbit(eventmask, BRCMF_E_DISASSOC_IND);
- setbit(eventmask, BRCMF_E_DISASSOC);
- setbit(eventmask, BRCMF_E_JOIN);
- setbit(eventmask, BRCMF_E_ASSOC_IND);
- setbit(eventmask, BRCMF_E_PSK_SUP);
- setbit(eventmask, BRCMF_E_LINK);
- setbit(eventmask, BRCMF_E_NDIS_LINK);
- setbit(eventmask, BRCMF_E_MIC_ERROR);
- setbit(eventmask, BRCMF_E_PMKID_CACHE);
- setbit(eventmask, BRCMF_E_TXFAIL);
- setbit(eventmask, BRCMF_E_JOIN_START);
- setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
-
- brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
- sizeof(iovbuf));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
- if (err) {
- WL_ERR("Set event_msgs error (%d)\n", err);
- goto dongle_eventmsg_out;
- }
-
-dongle_eventmsg_out:
- WL_TRACE("Exit\n");
- return err;
-}
-
-static s32
-brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
-{
- s8 iovbuf[32];
- s32 roamtrigger[2];
- s32 roam_delta[2];
- s32 err = 0;
-
- /*
- * Setup timeout if Beacons are lost and roam is
- * off to report link down
- */
- if (roamvar) {
- brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
- sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
- iovbuf, sizeof(iovbuf));
- if (err) {
- WL_ERR("bcn_timeout error (%d)\n", err);
- goto dongle_rom_out;
- }
- }
-
- /*
- * Enable/Disable built-in roaming to allow supplicant
- * to take care of roaming
- */
- WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
- brcmu_mkiovar("roam_off", (char *)&roamvar,
- sizeof(roamvar), iovbuf, sizeof(iovbuf));
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
- if (err) {
- WL_ERR("roam_off error (%d)\n", err);
- goto dongle_rom_out;
- }
-
- roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
- roamtrigger[1] = BRCM_BAND_ALL;
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
- (void *)roamtrigger, sizeof(roamtrigger));
- if (err) {
- WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
- goto dongle_rom_out;
- }
-
- roam_delta[0] = WL_ROAM_DELTA;
- roam_delta[1] = BRCM_BAND_ALL;
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
- (void *)roam_delta, sizeof(roam_delta));
- if (err) {
- WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
- goto dongle_rom_out;
- }
-
-dongle_rom_out:
- return err;
-}
-
-static s32
-brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
- s32 scan_unassoc_time, s32 scan_passive_time)
-{
- s32 err = 0;
-
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
- &scan_assoc_time, sizeof(scan_assoc_time));
- if (err) {
- if (err == -EOPNOTSUPP)
- WL_INFO("Scan assoc time is not supported\n");
- else
- WL_ERR("Scan assoc time error (%d)\n", err);
- goto dongle_scantime_out;
- }
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
- &scan_unassoc_time, sizeof(scan_unassoc_time));
- if (err) {
- if (err == -EOPNOTSUPP)
- WL_INFO("Scan unassoc time is not supported\n");
- else
- WL_ERR("Scan unassoc time error (%d)\n", err);
- goto dongle_scantime_out;
- }
-
- err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
- &scan_passive_time, sizeof(scan_passive_time));
- if (err) {
- if (err == -EOPNOTSUPP)
- WL_INFO("Scan passive time is not supported\n");
- else
- WL_ERR("Scan passive time error (%d)\n", err);
- goto dongle_scantime_out;
- }
-
-dongle_scantime_out:
- return err;
-}
-
-static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct wiphy *wiphy;
- s32 phy_list;
- s8 phy;
- s32 err = 0;
-
- err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
- &phy_list, sizeof(phy_list));
- if (err) {
- WL_ERR("error (%d)\n", err);
- return err;
- }
-
- phy = ((char *)&phy_list)[1];
- WL_INFO("%c phy\n", phy);
- if (phy == 'n' || phy == 'a') {
- wiphy = cfg_to_wiphy(cfg_priv);
- wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
- }
-
- return err;
-}
-
-static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
-{
- return wl_update_wiphybands(cfg_priv);
-}
-
-static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
-{
- struct net_device *ndev;
- struct wireless_dev *wdev;
- s32 power_mode;
- s32 err = 0;
-
- if (cfg_priv->dongle_up)
- return err;
-
- ndev = cfg_to_ndev(cfg_priv);
- wdev = ndev->ieee80211_ptr;
-
- brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
- WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
-
- err = brcmf_dongle_eventmsg(ndev);
- if (err)
- goto default_conf_out;
-
- power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
- err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
- if (err)
- goto default_conf_out;
- WL_INFO("power save set to %s\n",
- (power_mode ? "enabled" : "disabled"));
-
- err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
- WL_BEACON_TIMEOUT);
- if (err)
- goto default_conf_out;
- err = brcmf_dongle_mode(ndev, wdev->iftype);
- if (err && err != -EINPROGRESS)
- goto default_conf_out;
- err = brcmf_dongle_probecap(cfg_priv);
- if (err)
- goto default_conf_out;
-
- /* -EINPROGRESS: Call commit handler */
-
-default_conf_out:
-
- cfg_priv->dongle_up = true;
-
- return err;
-
-}
-
-static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
-{
- char buf[10+IFNAMSIZ];
- struct dentry *fd;
- s32 err = 0;
-
- sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
- cfg_priv->debugfsdir = debugfs_create_dir(buf,
- cfg_to_wiphy(cfg_priv)->debugfsdir);
-
- fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
- (u16 *)&cfg_priv->profile->beacon_interval);
- if (!fd) {
- err = -ENOMEM;
- goto err_out;
- }
-
- fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
- (u8 *)&cfg_priv->profile->dtim_period);
- if (!fd) {
- err = -ENOMEM;
- goto err_out;
- }
-
-err_out:
- return err;
-}
-
-static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
-{
- debugfs_remove_recursive(cfg_priv->debugfsdir);
- cfg_priv->debugfsdir = NULL;
-}
-
-static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
-{
- s32 err = 0;
-
- set_bit(WL_STATUS_READY, &cfg_priv->status);
-
- brcmf_debugfs_add_netdev_params(cfg_priv);
-
- err = brcmf_config_dongle(cfg_priv);
- if (err)
- return err;
-
- brcmf_invoke_iscan(cfg_priv);
-
- return err;
-}
-
-static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
-{
- /*
- * While going down, if associated with AP disassociate
- * from AP to save power
- */
- if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
- test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
- test_bit(WL_STATUS_READY, &cfg_priv->status)) {
- WL_INFO("Disassociating from AP");
- brcmf_link_down(cfg_priv);
-
- /* Make sure WPA_Supplicant receives all the event
- generated due to DISASSOC call to the fw to keep
- the state fw and WPA_Supplicant state consistent
- */
- brcmf_delay(500);
- }
-
- set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
- brcmf_term_iscan(cfg_priv);
- if (cfg_priv->scan_request) {
- cfg80211_scan_done(cfg_priv->scan_request, true);
- /* May need to perform this to cover rmmod */
- /* wl_set_mpc(cfg_to_ndev(wl), 1); */
- cfg_priv->scan_request = NULL;
- }
- clear_bit(WL_STATUS_READY, &cfg_priv->status);
- clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
- clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
-
- brcmf_debugfs_remove_netdev(cfg_priv);
-
- return 0;
-}
-
-s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
-{
- struct brcmf_cfg80211_priv *cfg_priv;
- s32 err = 0;
-
- cfg_priv = brcmf_priv_get(cfg_dev);
- mutex_lock(&cfg_priv->usr_sync);
- err = __brcmf_cfg80211_up(cfg_priv);
- mutex_unlock(&cfg_priv->usr_sync);
-
- return err;
-}
-
-s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
-{
- struct brcmf_cfg80211_priv *cfg_priv;
- s32 err = 0;
-
- cfg_priv = brcmf_priv_get(cfg_dev);
- mutex_lock(&cfg_priv->usr_sync);
- err = __brcmf_cfg80211_down(cfg_priv);
- mutex_unlock(&cfg_priv->usr_sync);
-
- return err;
-}
-
-static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
- u8 t, u8 l, u8 *v)
-{
- struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
- s32 err = 0;
-
- if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
- WL_ERR("ei crosses buffer boundary\n");
- return -ENOSPC;
- }
- ie->buf[ie->offset] = t;
- ie->buf[ie->offset + 1] = l;
- memcpy(&ie->buf[ie->offset + 2], v, l);
- ie->offset += l + 2;
-
- return err;
-}
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
deleted file mode 100644
index e69f4f6bf946..000000000000
--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _wl_cfg80211_h_
-#define _wl_cfg80211_h_
-
-struct brcmf_cfg80211_conf;
-struct brcmf_cfg80211_iface;
-struct brcmf_cfg80211_priv;
-struct brcmf_cfg80211_security;
-struct brcmf_cfg80211_ibss;
-
-#define WL_DBG_NONE 0
-#define WL_DBG_CONN (1 << 5)
-#define WL_DBG_SCAN (1 << 4)
-#define WL_DBG_TRACE (1 << 3)
-#define WL_DBG_INFO (1 << 1)
-#define WL_DBG_ERR (1 << 0)
-#define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
- (WL_DBG_SCAN) | (WL_DBG_CONN))
-
-#define WL_ERR(fmt, args...) \
-do { \
- if (brcmf_dbg_level & WL_DBG_ERR) { \
- if (net_ratelimit()) { \
- printk(KERN_ERR "ERROR @%s : " fmt, \
- __func__, ##args); \
- } \
- } \
-} while (0)
-
-#if (defined BCMDBG)
-#define WL_INFO(fmt, args...) \
-do { \
- if (brcmf_dbg_level & WL_DBG_INFO) { \
- if (net_ratelimit()) { \
- printk(KERN_ERR "INFO @%s : " fmt, \
- __func__, ##args); \
- } \
- } \
-} while (0)
-
-#define WL_TRACE(fmt, args...) \
-do { \
- if (brcmf_dbg_level & WL_DBG_TRACE) { \
- if (net_ratelimit()) { \
- printk(KERN_ERR "TRACE @%s : " fmt, \
- __func__, ##args); \
- } \
- } \
-} while (0)
-
-#define WL_SCAN(fmt, args...) \
-do { \
- if (brcmf_dbg_level & WL_DBG_SCAN) { \
- if (net_ratelimit()) { \
- printk(KERN_ERR "SCAN @%s : " fmt, \
- __func__, ##args); \
- } \
- } \
-} while (0)
-
-#define WL_CONN(fmt, args...) \
-do { \
- if (brcmf_dbg_level & WL_DBG_CONN) { \
- if (net_ratelimit()) { \
- printk(KERN_ERR "CONN @%s : " fmt, \
- __func__, ##args); \
- } \
- } \
-} while (0)
-
-#else /* (defined BCMDBG) */
-#define WL_INFO(fmt, args...)
-#define WL_TRACE(fmt, args...)
-#define WL_SCAN(fmt, args...)
-#define WL_CONN(fmt, args...)
-#endif /* (defined BCMDBG) */
-
-#define WL_NUM_SCAN_MAX 1
-#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used
- * for 2.6.33 kernel
- * or later
- */
-#define WL_SCAN_BUF_MAX (1024 * 8)
-#define WL_TLV_INFO_MAX 1024
-#define WL_BSS_INFO_MAX 2048
-#define WL_ASSOC_INFO_MAX 512 /*
- * needs to grab assoc info from dongle to
- * report it to cfg80211 through "connect"
- * event
- */
-#define WL_DCMD_LEN_MAX 1024
-#define WL_EXTRA_BUF_MAX 2048
-#define WL_ISCAN_BUF_MAX 2048 /*
- * the buf length can be BRCMF_DCMD_MAXLEN
- * to reduce iteration
- */
-#define WL_ISCAN_TIMER_INTERVAL_MS 3000
-#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1)
-#define WL_AP_MAX 256 /* virtually unlimitted as long
- * as kernel memory allows
- */
-
-#define WL_ROAM_TRIGGER_LEVEL -75
-#define WL_ROAM_DELTA 20
-#define WL_BEACON_TIMEOUT 3
-
-#define WL_SCAN_CHANNEL_TIME 40
-#define WL_SCAN_UNASSOC_TIME 40
-#define WL_SCAN_PASSIVE_TIME 120
-
-/* dongle status */
-enum wl_status {
- WL_STATUS_READY,
- WL_STATUS_SCANNING,
- WL_STATUS_SCAN_ABORTING,
- WL_STATUS_CONNECTING,
- WL_STATUS_CONNECTED
-};
-
-/* wi-fi mode */
-enum wl_mode {
- WL_MODE_BSS,
- WL_MODE_IBSS,
- WL_MODE_AP
-};
-
-/* dongle profile list */
-enum wl_prof_list {
- WL_PROF_MODE,
- WL_PROF_SSID,
- WL_PROF_SEC,
- WL_PROF_IBSS,
- WL_PROF_BAND,
- WL_PROF_BSSID,
- WL_PROF_ACT,
- WL_PROF_BEACONINT,
- WL_PROF_DTIMPERIOD
-};
-
-/* dongle iscan state */
-enum wl_iscan_state {
- WL_ISCAN_STATE_IDLE,
- WL_ISCAN_STATE_SCANING
-};
-
-/* dongle configuration */
-struct brcmf_cfg80211_conf {
- u32 mode; /* adhoc , infrastructure or ap */
- u32 frag_threshold;
- u32 rts_threshold;
- u32 retry_short;
- u32 retry_long;
- s32 tx_power;
- struct ieee80211_channel channel;
-};
-
-/* cfg80211 main event loop */
-struct brcmf_cfg80211_event_loop {
- s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
- struct net_device *ndev,
- const struct brcmf_event_msg *e,
- void *data);
-};
-
-/* representing interface of cfg80211 plane */
-struct brcmf_cfg80211_iface {
- struct brcmf_cfg80211_priv *cfg_priv;
-};
-
-struct brcmf_cfg80211_dev {
- void *driver_data; /* to store cfg80211 object information */
-};
-
-/* basic structure of scan request */
-struct brcmf_cfg80211_scan_req {
- struct brcmf_ssid_le ssid_le;
-};
-
-/* basic structure of information element */
-struct brcmf_cfg80211_ie {
- u16 offset;
- u8 buf[WL_TLV_INFO_MAX];
-};
-
-/* event queue for cfg80211 main event */
-struct brcmf_cfg80211_event_q {
- struct list_head evt_q_list;
- u32 etype;
- struct brcmf_event_msg emsg;
- s8 edata[1];
-};
-
-/* security information with currently associated ap */
-struct brcmf_cfg80211_security {
- u32 wpa_versions;
- u32 auth_type;
- u32 cipher_pairwise;
- u32 cipher_group;
- u32 wpa_auth;
-};
-
-/* ibss information for currently joined ibss network */
-struct brcmf_cfg80211_ibss {
- u8 beacon_interval; /* in millisecond */
- u8 atim; /* in millisecond */
- s8 join_only;
- u8 band;
- u8 channel;
-};
-
-/* dongle profile */
-struct brcmf_cfg80211_profile {
- u32 mode;
- struct brcmf_ssid ssid;
- u8 bssid[ETH_ALEN];
- u16 beacon_interval;
- u8 dtim_period;
- struct brcmf_cfg80211_security sec;
- struct brcmf_cfg80211_ibss ibss;
- s32 band;
-};
-
-/* dongle iscan event loop */
-struct brcmf_cfg80211_iscan_eloop {
- s32 (*handler[WL_SCAN_ERSULTS_LAST])
- (struct brcmf_cfg80211_priv *cfg_priv);
-};
-
-/* dongle iscan controller */
-struct brcmf_cfg80211_iscan_ctrl {
- struct net_device *ndev;
- struct timer_list timer;
- u32 timer_ms;
- u32 timer_on;
- s32 state;
- struct work_struct work;
- struct brcmf_cfg80211_iscan_eloop el;
- void *data;
- s8 dcmd_buf[BRCMF_DCMD_SMLEN];
- s8 scan_buf[WL_ISCAN_BUF_MAX];
-};
-
-/* association inform */
-struct brcmf_cfg80211_connect_info {
- u8 *req_ie;
- s32 req_ie_len;
- u8 *resp_ie;
- s32 resp_ie_len;
-};
-
-/* assoc ie length */
-struct brcmf_cfg80211_assoc_ielen {
- u32 req_len;
- u32 resp_len;
-};
-
-/* wpa2 pmk list */
-struct brcmf_cfg80211_pmk_list {
- struct pmkid_list pmkids;
- struct pmkid foo[MAXPMKID - 1];
-};
-
-/* dongle private data of cfg80211 interface */
-struct brcmf_cfg80211_priv {
- struct wireless_dev *wdev; /* representing wl cfg80211 device */
- struct brcmf_cfg80211_conf *conf; /* dongle configuration */
- struct cfg80211_scan_request *scan_request; /* scan request
- object */
- struct brcmf_cfg80211_event_loop el; /* main event loop */
- struct list_head evt_q_list; /* used for event queue */
- spinlock_t evt_q_lock; /* for event queue synchronization */
- struct mutex usr_sync; /* maily for dongle up/down synchronization */
- struct brcmf_scan_results *bss_list; /* bss_list holding scanned
- ap information */
- struct brcmf_scan_results *scan_results;
- struct brcmf_cfg80211_scan_req *scan_req_int; /* scan request object
- for internal purpose */
- struct wl_cfg80211_bss_info *bss_info; /* bss information for
- cfg80211 layer */
- struct brcmf_cfg80211_ie ie; /* information element object for
- internal purpose */
- struct brcmf_cfg80211_profile *profile; /* holding dongle profile */
- struct brcmf_cfg80211_iscan_ctrl *iscan; /* iscan controller */
- struct brcmf_cfg80211_connect_info conn_info; /* association info */
- struct brcmf_cfg80211_pmk_list *pmk_list; /* wpa2 pmk list */
- struct work_struct event_work; /* event handler work struct */
- unsigned long status; /* current dongle status */
- void *pub;
- u32 channel; /* current channel */
- bool iscan_on; /* iscan on/off switch */
- bool iscan_kickstart; /* indicate iscan already started */
- bool active_scan; /* current scan mode */
- bool ibss_starter; /* indicates this sta is ibss starter */
- bool link_up; /* link/connection up flag */
- bool pwr_save; /* indicate whether dongle to support
- power save mode */
- bool dongle_up; /* indicate whether dongle up or not */
- bool roam_on; /* on/off switch for dongle self-roaming */
- bool scan_tried; /* indicates if first scan attempted */
- u8 *dcmd_buf; /* dcmd buffer */
- u8 *extra_buf; /* maily to grab assoc information */
- struct dentry *debugfsdir;
- u8 ci[0] __aligned(NETDEV_ALIGN);
-};
-
-static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w)
-{
- return w->wdev->wiphy;
-}
-
-static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w)
-{
- return (struct brcmf_cfg80211_priv *)(wiphy_priv(w));
-}
-
-static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd)
-{
- return (struct brcmf_cfg80211_priv *)(wdev_priv(wd));
-}
-
-static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg)
-{
- return cfg->wdev->netdev;
-}
-
-static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev)
-{
- return wdev_to_cfg(ndev->ieee80211_ptr);
-}
-
-#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
-#define cfg_to_iscan(w) (w->iscan)
-
-static inline struct
-brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg)
-{
- return &cfg->conn_info;
-}
-
-static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list,
- struct brcmf_bss_info *bss)
-{
- return bss = bss ?
- (struct brcmf_bss_info *)((unsigned long)bss +
- le32_to_cpu(bss->length)) :
- list->bss_info;
-}
-
-extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
- struct device *busdev,
- void *data);
-extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg);
-
-/* event handler from dongle */
-extern void brcmf_cfg80211_event(struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data);
-extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev);
-extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev);
-
-#endif /* _wl_cfg80211_h_ */