diff options
author | Arend van Spriel <arend@broadcom.com> | 2011-10-05 13:19:03 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-10-11 15:55:30 -0400 |
commit | 5b435de0d786869c95d1962121af0d7df2542009 (patch) | |
tree | 9b7cfbc4aa9f1ec0e719e3a0c677bd9f4e56540d | |
parent | 5f68a2b0a890d086e40fc7b55f4a0c32c28bc0d2 (diff) |
net: wireless: add brcm80211 drivers
Add the brcm80211 tree to drivers/net/wireless, and disable the version that's
in drivers/staging. This version includes the sources currently in staging,
plus any changes that have been sent out for review.
Sources in staging will be deleted in a followup patch.
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
81 files changed, 97056 insertions, 3 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index f354bd4e121..abd3b71cd4a 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -271,6 +271,7 @@ config MWL8K source "drivers/net/wireless/ath/Kconfig" source "drivers/net/wireless/b43/Kconfig" source "drivers/net/wireless/b43legacy/Kconfig" +source "drivers/net/wireless/brcm80211/Kconfig" source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/ipw2x00/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 4cf0ad312da..0a304b060b6 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -58,3 +58,6 @@ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ obj-$(CONFIG_IWM) += iwmc3200wifi/ obj-$(CONFIG_MWIFIEX) += mwifiex/ +obj-$(CONFIG_BRCMFMAC) += brcm80211/ +obj-$(CONFIG_BRCMUMAC) += brcm80211/ +obj-$(CONFIG_BRCMSMAC) += brcm80211/ diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig new file mode 100644 index 00000000000..2069fc8f7ad --- /dev/null +++ b/drivers/net/wireless/brcm80211/Kconfig @@ -0,0 +1,35 @@ +config BRCMUTIL + tristate + +config BRCMSMAC + tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" + depends on PCI + depends on MAC80211 + depends on BCMA=n + select BRCMUTIL + select FW_LOADER + select CRC_CCITT + select CRC8 + select CORDIC + ---help--- + This module adds support for PCIe wireless adapters based on Broadcom + IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll + be called brcmsmac.ko. + +config BRCMFMAC + tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver" + depends on MMC + depends on CFG80211 + select BRCMUTIL + select FW_LOADER + ---help--- + This module adds support for embedded wireless adapters based on + Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's + wireless extensions subsystem. If you choose to build a module, + it'll be called brcmfmac.ko. + +config BRCMDBG + bool "Broadcom driver debug functions" + depends on BRCMSMAC || BRCMFMAC + ---help--- + Selecting this enables additional code for debug purposes. diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile new file mode 100644 index 00000000000..f41c047eca8 --- /dev/null +++ b/drivers/net/wireless/brcm80211/Makefile @@ -0,0 +1,23 @@ +# +# 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. + +# common flags +subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG + +obj-$(CONFIG_BRCMUTIL) += brcmutil/ +obj-$(CONFIG_BRCMFMAC) += brcmfmac/ +obj-$(CONFIG_BRCMSMAC) += brcmsmac/ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile new file mode 100644 index 00000000000..b44e3094588 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -0,0 +1,33 @@ +# +# 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/net/wireless/brcm80211/brcmfmac \ + -Idrivers/net/wireless/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/net/wireless/brcm80211/brcmfmac/bcmchip.h b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h new file mode 100644 index 00000000000..d7d3afd5a10 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h @@ -0,0 +1,32 @@ +/* + * 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/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c new file mode 100644 index 00000000000..bff9dcd6fad --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -0,0 +1,371 @@ +/* + * 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, " |