mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
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>
This commit is contained in:
committed by
John W. Linville
parent
5f68a2b0a8
commit
5b435de0d7
@@ -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"
|
||||
|
||||
@@ -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/
|
||||
|
||||
35
drivers/net/wireless/brcm80211/Kconfig
Normal file
35
drivers/net/wireless/brcm80211/Kconfig
Normal file
@@ -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.
|
||||
23
drivers/net/wireless/brcm80211/Makefile
Normal file
23
drivers/net/wireless/brcm80211/Makefile
Normal file
@@ -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/
|
||||
33
drivers/net/wireless/brcm80211/brcmfmac/Makefile
Normal file
33
drivers/net/wireless/brcm80211/brcmfmac/Makefile
Normal file
@@ -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__
|
||||
32
drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
Normal file
32
drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
Normal file
@@ -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_ */
|
||||
371
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
Normal file
371
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
Normal file
@@ -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, "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);
|
||||
}
|
||||
625
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
Normal file
625
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
Normal file
File diff suppressed because it is too large
Load Diff
773
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
Normal file
773
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
Normal file
File diff suppressed because it is too large
Load Diff
57
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
Normal file
57
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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_ */
|
||||
498
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
Normal file
498
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
Normal file
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
* 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 */
|
||||
}
|
||||
872
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
Normal file
872
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
Normal file
File diff suppressed because it is too large
Load Diff
58
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
Normal file
58
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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_ */
|
||||
1354
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
Normal file
1354
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
Normal file
File diff suppressed because it is too large
Load Diff
60
drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
Normal file
60
drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_ */
|
||||
4581
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
Normal file
4581
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
Normal file
File diff suppressed because it is too large
Load Diff
252
drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
Normal file
252
drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* 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_ */
|
||||
3730
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
Normal file
3730
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
Normal file
File diff suppressed because it is too large
Load Diff
375
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
Normal file
375
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* 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_ */
|
||||
51
drivers/net/wireless/brcm80211/brcmsmac/Makefile
Normal file
51
drivers/net/wireless/brcm80211/brcmsmac/Makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# 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 := \
|
||||
-D__CHECK_ENDIAN__ \
|
||||
-Idrivers/net/wireless/brcm80211/brcmsmac \
|
||||
-Idrivers/net/wireless/brcm80211/brcmsmac/phy \
|
||||
-Idrivers/net/wireless/brcm80211/include
|
||||
|
||||
BRCMSMAC_OFILES := \
|
||||
mac80211_if.o \
|
||||
ucode_loader.o \
|
||||
ampdu.o \
|
||||
antsel.o \
|
||||
channel.o \
|
||||
main.o \
|
||||
phy_shim.o \
|
||||
pmu.o \
|
||||
rate.o \
|
||||
stf.o \
|
||||
aiutils.o \
|
||||
phy/phy_cmn.o \
|
||||
phy/phy_lcn.o \
|
||||
phy/phy_n.o \
|
||||
phy/phytbl_lcn.o \
|
||||
phy/phytbl_n.o \
|
||||
phy/phy_qmath.o \
|
||||
otp.o \
|
||||
srom.o \
|
||||
dma.o \
|
||||
nicpci.o \
|
||||
brcms_trace_events.o
|
||||
|
||||
MODULEPFX := brcmsmac
|
||||
|
||||
obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
|
||||
$(MODULEPFX)-objs = $(BRCMSMAC_OFILES)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user