mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-12 23:26:40 +07: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:
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
@ -0,0 +1,625 @@
|
||||
/*
|
||||
* 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,
|
||||
®data)) != 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);
|
||||
}
|
773
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
Normal file
773
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
Normal file
@ -0,0 +1,773 @@
|
||||
/*
|
||||
* 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_ */
|
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
@ -0,0 +1,872 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
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)
|
2079
drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
Normal file
2079
drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
Normal file
File diff suppressed because it is too large
Load Diff
378
drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
Normal file
378
drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* 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 _BRCM_AIUTILS_H_
|
||||
#define _BRCM_AIUTILS_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* SOC Interconnect Address Map.
|
||||
* All regions may not exist on all chips.
|
||||
*/
|
||||
/* each core gets 4Kbytes for registers */
|
||||
#define SI_CORE_SIZE 0x1000
|
||||
/*
|
||||
* Max cores (this is arbitrary, for software
|
||||
* convenience and could be changed if we
|
||||
* make any larger chips
|
||||
*/
|
||||
#define SI_MAXCORES 16
|
||||
|
||||
/* Client Mode sb2pcitranslation2 size in bytes */
|
||||
#define SI_PCI_DMA_SZ 0x40000000
|
||||
|
||||
/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
|
||||
#define SI_PCIE_DMA_H32 0x80000000
|
||||
|
||||
/* core codes */
|
||||
#define NODEV_CORE_ID 0x700 /* Invalid coreid */
|
||||
#define CC_CORE_ID 0x800 /* chipcommon core */
|
||||
#define ILINE20_CORE_ID 0x801 /* iline20 core */
|
||||
#define SRAM_CORE_ID 0x802 /* sram core */
|
||||
#define SDRAM_CORE_ID 0x803 /* sdram core */
|
||||
#define PCI_CORE_ID 0x804 /* pci core */
|
||||
#define MIPS_CORE_ID 0x805 /* mips core */
|
||||
#define ENET_CORE_ID 0x806 /* enet mac core */
|
||||
#define CODEC_CORE_ID 0x807 /* v90 codec core */
|
||||
#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
|
||||
#define ADSL_CORE_ID 0x809 /* ADSL core */
|
||||
#define ILINE100_CORE_ID 0x80a /* iline100 core */
|
||||
#define IPSEC_CORE_ID 0x80b /* ipsec core */
|
||||
#define UTOPIA_CORE_ID 0x80c /* utopia core */
|
||||
#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
|
||||
#define SOCRAM_CORE_ID 0x80e /* internal memory core */
|
||||
#define MEMC_CORE_ID 0x80f /* memc sdram core */
|
||||
#define OFDM_CORE_ID 0x810 /* OFDM phy core */
|
||||
#define EXTIF_CORE_ID 0x811 /* external interface core */
|
||||
#define D11_CORE_ID 0x812 /* 802.11 MAC core */
|
||||
#define APHY_CORE_ID 0x813 /* 802.11a phy core */
|
||||
#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
|
||||
#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
|
||||
#define MIPS33_CORE_ID 0x816 /* mips3302 core */
|
||||
#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
|
||||
#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
|
||||
#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
|
||||
#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
|
||||
#define SDIOH_CORE_ID 0x81b /* sdio host core */
|
||||
#define ROBO_CORE_ID 0x81c /* roboswitch core */
|
||||
#define ATA100_CORE_ID 0x81d /* parallel ATA core */
|
||||
#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
|
||||
#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
|
||||
#define PCIE_CORE_ID 0x820 /* pci express core */
|
||||
#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
|
||||
#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
|
||||
#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
|
||||
#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
|
||||
#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
|
||||
#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
|
||||
#define PMU_CORE_ID 0x827 /* PMU core */
|
||||
#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
|
||||
#define SDIOD_CORE_ID 0x829 /* SDIO device core */
|
||||
#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
|
||||
#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
|
||||
#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
|
||||
#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
|
||||
#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
|
||||
#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
|
||||
#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
|
||||
#define SC_CORE_ID 0x831 /* shared common core */
|
||||
#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
|
||||
#define SPIH_CORE_ID 0x833 /* SPI host core */
|
||||
#define I2S_CORE_ID 0x834 /* I2S core */
|
||||
#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
|
||||
#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
|
||||
#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
|
||||
#define DEF_AI_COMP 0xfff /* Default component, in ai chips it
|
||||
* maps all unused address ranges
|
||||
*/
|
||||
|
||||
/* chipcommon being the first core: */
|
||||
#define SI_CC_IDX 0
|
||||
|
||||
/* SOC Interconnect types (aka chip types) */
|
||||
#define SOCI_AI 1
|
||||
|
||||
/* Common core control flags */
|
||||
#define SICF_BIST_EN 0x8000
|
||||
#define SICF_PME_EN 0x4000
|
||||
#define SICF_CORE_BITS 0x3ffc
|
||||
#define SICF_FGC 0x0002
|
||||
#define SICF_CLOCK_EN 0x0001
|
||||
|
||||
/* Common core status flags */
|
||||
#define SISF_BIST_DONE 0x8000
|
||||
#define SISF_BIST_ERROR 0x4000
|
||||
#define SISF_GATED_CLK 0x2000
|
||||
#define SISF_DMA64 0x1000
|
||||
#define SISF_CORE_BITS 0x0fff
|
||||
|
||||
/* A register that is common to all cores to
|
||||
* communicate w/PMU regarding clock control.
|
||||
*/
|
||||
#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */
|
||||
|
||||
/* clk_ctl_st register */
|
||||
#define CCS_FORCEALP 0x00000001 /* force ALP request */
|
||||
#define CCS_FORCEHT 0x00000002 /* force HT request */
|
||||
#define CCS_FORCEILP 0x00000004 /* force ILP request */
|
||||
#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
|
||||
#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
|
||||
#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
|
||||
#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */
|
||||
#define CCS_ERSRC_REQ_SHIFT 8
|
||||
#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
|
||||
#define CCS_HTAVAIL 0x00020000 /* HT is available */
|
||||
#define CCS_BP_ON_APL 0x00040000 /* RO: running on ALP clock */
|
||||
#define CCS_BP_ON_HT 0x00080000 /* RO: running on HT clock */
|
||||
#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */
|
||||
#define CCS_ERSRC_STS_SHIFT 24
|
||||
|
||||
/* HT avail in chipc and pcmcia on 4328a0 */
|
||||
#define CCS0_HTAVAIL 0x00010000
|
||||
/* ALP avail in chipc and pcmcia on 4328a0 */
|
||||
#define CCS0_ALPAVAIL 0x00020000
|
||||
|
||||
/* Not really related to SOC Interconnect, but a couple of software
|
||||
* conventions for the use the flash space:
|
||||
*/
|
||||
|
||||
/* Minumum amount of flash we support */
|
||||
#define FLASH_MIN 0x00020000 /* Minimum flash size */
|
||||
|
||||
#define CC_SROM_OTP 0x800 /* SROM/OTP address space */
|
||||
|
||||
/* gpiotimerval */
|
||||
#define GPIO_ONTIME_SHIFT 16
|
||||
|
||||
/* Fields in clkdiv */
|
||||
#define CLKD_OTP 0x000f0000
|
||||
#define CLKD_OTP_SHIFT 16
|
||||
|
||||
/* Package IDs */
|
||||
#define BCM4717_PKG_ID 9 /* 4717 package id */
|
||||
#define BCM4718_PKG_ID 10 /* 4718 package id */
|
||||
#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */
|
||||
|
||||
/* these are router chips */
|
||||
#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */
|
||||
#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */
|
||||
#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */
|
||||
|
||||
/* dynamic clock control defines */
|
||||
#define LPOMINFREQ 25000 /* low power oscillator min */
|
||||
#define LPOMAXFREQ 43000 /* low power oscillator max */
|
||||
#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
|
||||
#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
|
||||
#define PCIMINFREQ 25000000 /* 25 MHz */
|
||||
#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
|
||||
|
||||
#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
|
||||
#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
|
||||
|
||||
/* clkctl xtal what flags */
|
||||
#define XTAL 0x1 /* primary crystal oscillator (2050) */
|
||||
#define PLL 0x2 /* main chip pll */
|
||||
|
||||
/* clkctl clk mode */
|
||||
#define CLK_FAST 0 /* force fast (pll) clock */
|
||||
#define CLK_DYNAMIC 2 /* enable dynamic clock control */
|
||||
|
||||
/* GPIO usage priorities */
|
||||
#define GPIO_DRV_PRIORITY 0 /* Driver */
|
||||
#define GPIO_APP_PRIORITY 1 /* Application */
|
||||
#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO
|
||||
* reservation
|
||||
*/
|
||||
|
||||
/* GPIO pull up/down */
|
||||
#define GPIO_PULLUP 0
|
||||
#define GPIO_PULLDN 1
|
||||
|
||||
/* GPIO event regtype */
|
||||
#define GPIO_REGEVT 0 /* GPIO register event */
|
||||
#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
|
||||
#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
|
||||
|
||||
/* device path */
|
||||
#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
|
||||
|
||||
/* SI routine enumeration: to be used by update function with multiple hooks */
|
||||
#define SI_DOATTACH 1
|
||||
#define SI_PCIDOWN 2
|
||||
#define SI_PCIUP 3
|
||||
|
||||
/*
|
||||
* Data structure to export all chip specific common variables
|
||||
* public (read-only) portion of aiutils handle returned by si_attach()
|
||||
*/
|
||||
struct si_pub {
|
||||
uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
|
||||
uint buscorerev; /* buscore rev */
|
||||
uint buscoreidx; /* buscore index */
|
||||
int ccrev; /* chip common core rev */
|
||||
u32 cccaps; /* chip common capabilities */
|
||||
u32 cccaps_ext; /* chip common capabilities extension */
|
||||
int pmurev; /* pmu core rev */
|
||||
u32 pmucaps; /* pmu capabilities */
|
||||
uint boardtype; /* board type */
|
||||
uint boardvendor; /* board vendor */
|
||||
uint boardflags; /* board flags */
|
||||
uint boardflags2; /* board flags2 */
|
||||
uint chip; /* chip number */
|
||||
uint chiprev; /* chip revision */
|
||||
uint chippkg; /* chip package option */
|
||||
u32 chipst; /* chip status */
|
||||
bool issim; /* chip is in simulation or emulation */
|
||||
uint socirev; /* SOC interconnect rev */
|
||||
bool pci_pr32414;
|
||||
|
||||
};
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
struct gpioh_item {
|
||||
void *arg;
|
||||
bool level;
|
||||
void (*handler) (u32 stat, void *arg);
|
||||
u32 event;
|
||||
struct gpioh_item *next;
|
||||
};
|
||||
|
||||
/* misc si info needed by some of the routines */
|
||||
struct si_info {
|
||||
struct si_pub pub; /* back plane public state (must be first) */
|
||||
struct pci_dev *pbus; /* handle to pci bus */
|
||||
uint dev_coreid; /* the core provides driver functions */
|
||||
void *intr_arg; /* interrupt callback function arg */
|
||||
u32 (*intrsoff_fn) (void *intr_arg); /* turns chip interrupts off */
|
||||
/* restore chip interrupts */
|
||||
void (*intrsrestore_fn) (void *intr_arg, u32 arg);
|
||||
/* check if interrupts are enabled */
|
||||
bool (*intrsenabled_fn) (void *intr_arg);
|
||||
|
||||
struct pcicore_info *pch; /* PCI/E core handle */
|
||||
|
||||
struct list_head var_list; /* list of srom variables */
|
||||
|
||||
void __iomem *curmap; /* current regs va */
|
||||
void __iomem *regs[SI_MAXCORES]; /* other regs va */
|
||||
|
||||
uint curidx; /* current core index */
|
||||
uint numcores; /* # discovered cores */
|
||||
uint coreid[SI_MAXCORES]; /* id of each core */
|
||||
u32 coresba[SI_MAXCORES]; /* backplane address of each core */
|
||||
void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
|
||||
u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
|
||||
u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
|
||||
u32 coresba2_size[SI_MAXCORES]; /* second address space size */
|
||||
|
||||
void *curwrap; /* current wrapper va */
|
||||
void *wrappers[SI_MAXCORES]; /* other cores wrapper va */
|
||||
u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */
|
||||
|
||||
u32 cia[SI_MAXCORES]; /* erom cia entry for each core */
|
||||
u32 cib[SI_MAXCORES]; /* erom cia entry for each core */
|
||||
u32 oob_router; /* oob router registers for axi */
|
||||
};
|
||||
|
||||
/*
|
||||
* Many of the routines below take an 'sih' handle as their first arg.
|
||||
* Allocate this by calling si_attach(). Free it by calling si_detach().
|
||||
* At any one time, the sih is logically focused on one particular si core
|
||||
* (the "current core").
|
||||
* Use si_setcore() or si_setcoreidx() to change the association to another core
|
||||
*/
|
||||
|
||||
|
||||
/* AMBA Interconnect exported externs */
|
||||
extern uint ai_flag(struct si_pub *sih);
|
||||
extern void ai_setint(struct si_pub *sih, int siflag);
|
||||
extern uint ai_coreidx(struct si_pub *sih);
|
||||
extern uint ai_corevendor(struct si_pub *sih);
|
||||
extern uint ai_corerev(struct si_pub *sih);
|
||||
extern bool ai_iscoreup(struct si_pub *sih);
|
||||
extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
|
||||
uint val);
|
||||
extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
|
||||
extern void ai_core_disable(struct si_pub *sih, u32 bits);
|
||||
extern int ai_numaddrspaces(struct si_pub *sih);
|
||||
extern u32 ai_addrspace(struct si_pub *sih, uint asidx);
|
||||
extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx);
|
||||
extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val);
|
||||
|
||||
/* === exported functions === */
|
||||
extern struct si_pub *ai_attach(void __iomem *regs, struct pci_dev *sdh);
|
||||
extern void ai_detach(struct si_pub *sih);
|
||||
extern uint ai_coreid(struct si_pub *sih);
|
||||
extern uint ai_corerev(struct si_pub *sih);
|
||||
extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
|
||||
uint val);
|
||||
extern void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val);
|
||||
extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern bool ai_iscoreup(struct si_pub *sih);
|
||||
extern uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit);
|
||||
extern void __iomem *ai_setcoreidx(struct si_pub *sih, uint coreidx);
|
||||
extern void __iomem *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit);
|
||||
extern void __iomem *ai_switch_core(struct si_pub *sih, uint coreid,
|
||||
uint *origidx, uint *intr_val);
|
||||
extern void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val);
|
||||
extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
|
||||
extern void ai_core_disable(struct si_pub *sih, u32 bits);
|
||||
extern u32 ai_alp_clock(struct si_pub *sih);
|
||||
extern u32 ai_ilp_clock(struct si_pub *sih);
|
||||
extern void ai_pci_setup(struct si_pub *sih, uint coremask);
|
||||
extern void ai_setint(struct si_pub *sih, int siflag);
|
||||
extern bool ai_backplane64(struct si_pub *sih);
|
||||
extern void ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
|
||||
void *intrsrestore_fn,
|
||||
void *intrsenabled_fn, void *intr_arg);
|
||||
extern void ai_deregister_intr_callback(struct si_pub *sih);
|
||||
extern void ai_clkctl_init(struct si_pub *sih);
|
||||
extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
|
||||
extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
|
||||
extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on);
|
||||
extern bool ai_deviceremoved(struct si_pub *sih);
|
||||
extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val,
|
||||
u8 priority);
|
||||
|
||||
/* OTP status */
|
||||
extern bool ai_is_otp_disabled(struct si_pub *sih);
|
||||
|
||||
/* SPROM availability */
|
||||
extern bool ai_is_sprom_available(struct si_pub *sih);
|
||||
|
||||
/*
|
||||
* Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
|
||||
* The returned path is NULL terminated and has trailing '/'.
|
||||
* Return 0 on success, nonzero otherwise.
|
||||
*/
|
||||
extern int ai_devpath(struct si_pub *sih, char *path, int size);
|
||||
|
||||
extern void ai_pci_sleep(struct si_pub *sih);
|
||||
extern void ai_pci_down(struct si_pub *sih);
|
||||
extern void ai_pci_up(struct si_pub *sih);
|
||||
extern int ai_pci_fixcfg(struct si_pub *sih);
|
||||
|
||||
extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
|
||||
/* Enable Ex-PA for 4313 */
|
||||
extern void ai_epa_4313war(struct si_pub *sih);
|
||||
|
||||
#endif /* _BRCM_AIUTILS_H_ */
|
1241
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
Normal file
1241
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
Normal file
File diff suppressed because it is too large
Load Diff
30
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
Normal file
30
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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_AMPDU_H_
|
||||
#define _BRCM_AMPDU_H_
|
||||
|
||||
extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
|
||||
extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
|
||||
struct brcms_txq_info *qi,
|
||||
struct sk_buff **aggp, int prec);
|
||||
extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
|
||||
struct sk_buff *p, struct tx_status *txs);
|
||||
extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
|
||||
|
||||
#endif /* _BRCM_AMPDU_H_ */
|
307
drivers/net/wireless/brcm80211/brcmsmac/antsel.c
Normal file
307
drivers/net/wireless/brcm80211/brcmsmac/antsel.c
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* 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/slab.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "main.h"
|
||||
#include "phy_shim.h"
|
||||
#include "antsel.h"
|
||||
|
||||
#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
|
||||
#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
|
||||
#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */
|
||||
#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */
|
||||
#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */
|
||||
#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */
|
||||
|
||||
/* useful macros */
|
||||
#define BRCMS_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
|
||||
#define BRCMS_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf)
|
||||
#define BRCMS_ANTIDX_11N(ant) (((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
|
||||
(BRCMS_ANTSEL_11N_1(ant)))
|
||||
#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
|
||||
#define BRCMS_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK)
|
||||
|
||||
/* antenna switch */
|
||||
/* defines for no boardlevel antenna diversity */
|
||||
#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */
|
||||
|
||||
/* 2x3 antdiv defines and tables for GPIO communication */
|
||||
#define ANT_SELCFG_NUM_2x3 3
|
||||
#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */
|
||||
|
||||
/* 2x4 antdiv rev4 defines and tables for GPIO communication */
|
||||
#define ANT_SELCFG_NUM_2x4 4
|
||||
#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */
|
||||
|
||||
static const u16 mimo_2x4_div_antselpat_tbl[] = {
|
||||
0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */
|
||||
0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */
|
||||
0, 0, 0, 0, /* n.a. */
|
||||
0, 0, 0, 0 /* n.a. */
|
||||
};
|
||||
|
||||
static const u8 mimo_2x4_div_antselid_tbl[16] = {
|
||||
0, 0, 0, 0, 0, 2, 3, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */
|
||||
};
|
||||
|
||||
static const u16 mimo_2x3_div_antselpat_tbl[] = {
|
||||
16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */
|
||||
16, 16, 16, 16, /* n.a. */
|
||||
16, 2, 16, 16, /* ant0: 2 ant1: 1 */
|
||||
16, 16, 16, 16 /* n.a. */
|
||||
};
|
||||
|
||||
static const u8 mimo_2x3_div_antselid_tbl[16] = {
|
||||
0, 1, 2, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */
|
||||
};
|
||||
|
||||
/* boardlevel antenna selection: init antenna selection structure */
|
||||
static void
|
||||
brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
|
||||
bool auto_sel)
|
||||
{
|
||||
if (asi->antsel_type == ANTSEL_2x3) {
|
||||
u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
|
||||
((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
|
||||
antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x4) {
|
||||
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
|
||||
|
||||
} else { /* no antenna selection available */
|
||||
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->num_antcfg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct antsel_info *asi;
|
||||
struct si_pub *sih = wlc->hw->sih;
|
||||
|
||||
asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
|
||||
if (!asi)
|
||||
return NULL;
|
||||
|
||||
asi->wlc = wlc;
|
||||
asi->pub = wlc->pub;
|
||||
asi->antsel_type = ANTSEL_NA;
|
||||
asi->antsel_avail = false;
|
||||
asi->antsel_antswitch = (u8) getintvar(sih, BRCMS_SROM_ANTSWITCH);
|
||||
|
||||
if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
|
||||
switch (asi->antsel_antswitch) {
|
||||
case ANTSWITCH_TYPE_1:
|
||||
case ANTSWITCH_TYPE_2:
|
||||
case ANTSWITCH_TYPE_3:
|
||||
/* 4321/2 board with 2x3 switch logic */
|
||||
asi->antsel_type = ANTSEL_2x3;
|
||||
/* Antenna selection availability */
|
||||
if (((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) ||
|
||||
((u16) getintvar(sih, BRCMS_SROM_AA5G) == 7)) {
|
||||
asi->antsel_avail = true;
|
||||
} else if (
|
||||
(u16) getintvar(sih, BRCMS_SROM_AA2G) == 3 ||
|
||||
(u16) getintvar(sih, BRCMS_SROM_AA5G) == 3) {
|
||||
asi->antsel_avail = false;
|
||||
} else {
|
||||
asi->antsel_avail = false;
|
||||
wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
|
||||
"board cfg invalid\n");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if ((asi->pub->sromrev == 4) &&
|
||||
((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) &&
|
||||
((u16) getintvar(sih, BRCMS_SROM_AA5G) == 0)) {
|
||||
/* hack to match old 4321CB2 cards with 2of3 antenna switch */
|
||||
asi->antsel_type = ANTSEL_2x3;
|
||||
asi->antsel_avail = true;
|
||||
} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
|
||||
asi->antsel_type = ANTSEL_2x4;
|
||||
asi->antsel_avail = true;
|
||||
}
|
||||
|
||||
/* Set the antenna selection type for the low driver */
|
||||
brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
|
||||
|
||||
/* Init (auto/manual) antenna selection */
|
||||
brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
|
||||
brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
|
||||
|
||||
return asi;
|
||||
}
|
||||
|
||||
void brcms_c_antsel_detach(struct antsel_info *asi)
|
||||
{
|
||||
kfree(asi);
|
||||
}
|
||||
|
||||
/*
|
||||
* boardlevel antenna selection:
|
||||
* convert ant_cfg to mimo_antsel (ucode interface)
|
||||
*/
|
||||
static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
|
||||
{
|
||||
u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
|
||||
u16 mimo_antsel = 0;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
|
||||
return mimo_antsel;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
|
||||
return mimo_antsel;
|
||||
}
|
||||
|
||||
return mimo_antsel;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: ucode interface control */
|
||||
static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
|
||||
struct brcms_antselcfg *antsel)
|
||||
{
|
||||
struct brcms_c_info *wlc = asi->wlc;
|
||||
u8 ant_cfg;
|
||||
u16 mimo_antsel;
|
||||
|
||||
/* 1) Update TX antconfig for all frames that are not unicast data
|
||||
* (aka default TX)
|
||||
*/
|
||||
ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
|
||||
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
|
||||
brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
|
||||
/*
|
||||
* Update driver stats for currently selected
|
||||
* default tx/rx antenna config
|
||||
*/
|
||||
asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
|
||||
|
||||
/* 2) Update RX antconfig for all frames that are not unicast data
|
||||
* (aka default RX)
|
||||
*/
|
||||
ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
|
||||
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
|
||||
brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
|
||||
/*
|
||||
* Update driver stats for currently selected
|
||||
* default tx/rx antenna config
|
||||
*/
|
||||
asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcms_c_antsel_init(struct antsel_info *asi)
|
||||
{
|
||||
if ((asi->antsel_type == ANTSEL_2x3) ||
|
||||
(asi->antsel_type == ANTSEL_2x4))
|
||||
brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert id to ant_cfg */
|
||||
static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
|
||||
{
|
||||
u8 antcfg = ANT_SELCFG_DEF_2x2;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
|
||||
return antcfg;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
|
||||
return antcfg;
|
||||
}
|
||||
|
||||
return antcfg;
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
|
||||
u8 antselid, u8 fbantselid, u8 *antcfg,
|
||||
u8 *fbantcfg)
|
||||
{
|
||||
u8 ant;
|
||||
|
||||
/* if use default, assign it and return */
|
||||
if (usedef) {
|
||||
*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
|
||||
*fbantcfg = *antcfg;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sel) {
|
||||
*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
*fbantcfg = *antcfg;
|
||||
|
||||
} else {
|
||||
ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
|
||||
*antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
|
||||
*fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
|
||||
} else {
|
||||
*antcfg =
|
||||
asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
*fbantcfg = *antcfg;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
|
||||
u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
|
||||
{
|
||||
u8 antselid = 0;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
|
||||
return antselid;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
|
||||
return antselid;
|
||||
}
|
||||
|
||||
return antselid;
|
||||
}
|
29
drivers/net/wireless/brcm80211/brcmsmac/antsel.h
Normal file
29
drivers/net/wireless/brcm80211/brcmsmac/antsel.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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_ANTSEL_H_
|
||||
#define _BRCM_ANTSEL_H_
|
||||
|
||||
extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_antsel_detach(struct antsel_info *asi);
|
||||
extern void brcms_c_antsel_init(struct antsel_info *asi);
|
||||
extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
|
||||
bool sel,
|
||||
u8 id, u8 fbid, u8 *antcfg,
|
||||
u8 *fbantcfg);
|
||||
extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
|
||||
|
||||
#endif /* _BRCM_ANTSEL_H_ */
|
23
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
Normal file
23
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/module.h> /* bug in tracepoint.h, it should include this */
|
||||
|
||||
#ifndef __CHECKER__
|
||||
#include "mac80211_if.h"
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "brcms_trace_events.h"
|
||||
#endif
|
92
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
Normal file
92
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM brcmsmac
|
||||
|
||||
#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
|
||||
#define __TRACE_BRCMSMAC_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
#include "mac80211_if.h"
|
||||
|
||||
#ifndef CONFIG_BRCMDBG
|
||||
#undef TRACE_EVENT
|
||||
#define TRACE_EVENT(name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We define a tracepoint, its arguments, its printk format and its
|
||||
* 'fast binary record' layout.
|
||||
*/
|
||||
TRACE_EVENT(brcms_timer,
|
||||
/* TPPROTO is the prototype of the function called by this tracepoint */
|
||||
TP_PROTO(struct brcms_timer *t),
|
||||
/*
|
||||
* TPARGS(firstarg, p) are the parameters names, same as found in the
|
||||
* prototype.
|
||||
*/
|
||||
TP_ARGS(t),
|
||||
/*
|
||||
* Fast binary tracing: define the trace record via TP_STRUCT__entry().
|
||||
* You can think about it like a regular C structure local variable
|
||||
* definition.
|
||||
*/
|
||||
TP_STRUCT__entry(
|
||||
__field(uint, ms)
|
||||
__field(uint, set)
|
||||
__field(uint, periodic)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->ms = t->ms;
|
||||
__entry->set = t->set;
|
||||
__entry->periodic = t->periodic;
|
||||
),
|
||||
TP_printk(
|
||||
"ms=%u set=%u periodic=%u",
|
||||
__entry->ms, __entry->set, __entry->periodic
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcms_dpc,
|
||||
TP_PROTO(unsigned long data),
|
||||
TP_ARGS(data),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned long, data)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->data = data;
|
||||
),
|
||||
TP_printk(
|
||||
"data=%p",
|
||||
(void *)__entry->data
|
||||
)
|
||||
);
|
||||
|
||||
#endif /* __TRACE_BRCMSMAC_H */
|
||||
|
||||
#ifdef CONFIG_BRCMDBG
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE brcms_trace_events
|
||||
|
||||
#include <trace/define_trace.h>
|
||||
|
||||
#endif /* CONFIG_BRCMDBG */
|
1565
drivers/net/wireless/brcm80211/brcmsmac/channel.c
Normal file
1565
drivers/net/wireless/brcm80211/brcmsmac/channel.c
Normal file
File diff suppressed because it is too large
Load Diff
53
drivers/net/wireless/brcm80211/brcmsmac/channel.h
Normal file
53
drivers/net/wireless/brcm80211/brcmsmac/channel.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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_CHANNEL_H_
|
||||
#define _BRCM_CHANNEL_H_
|
||||
|
||||
/* conversion for phy txpwr calculations that use .25 dB units */
|
||||
#define BRCMS_TXPWR_DB_FACTOR 4
|
||||
|
||||
/* bits for locale_info flags */
|
||||
#define BRCMS_PEAK_CONDUCTED 0x00 /* Peak for locals */
|
||||
#define BRCMS_EIRP 0x01 /* Flag for EIRP */
|
||||
#define BRCMS_DFS_TPC 0x02 /* Flag for DFS TPC */
|
||||
#define BRCMS_NO_OFDM 0x04 /* Flag for No OFDM */
|
||||
#define BRCMS_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */
|
||||
#define BRCMS_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */
|
||||
#define BRCMS_RADAR_TYPE_EU 0x20 /* Flag for EU */
|
||||
#define BRCMS_DFS_FCC BRCMS_DFS_TPC /* Flag for DFS FCC */
|
||||
|
||||
#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
|
||||
|
||||
extern struct brcms_cm_info *
|
||||
brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
|
||||
|
||||
extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
|
||||
uint bandunit);
|
||||
|
||||
extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
|
||||
u16 chspec);
|
||||
|
||||
extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
|
||||
u16 chanspec,
|
||||
struct txpwr_limits *txpwr);
|
||||
extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
|
||||
u16 chanspec,
|
||||
u8 local_constraint_qdbm);
|
||||
|
||||
#endif /* _WLC_CHANNEL_H */
|
1898
drivers/net/wireless/brcm80211/brcmsmac/d11.h
Normal file
1898
drivers/net/wireless/brcm80211/brcmsmac/d11.h
Normal file
File diff suppressed because it is too large
Load Diff
1425
drivers/net/wireless/brcm80211/brcmsmac/dma.c
Normal file
1425
drivers/net/wireless/brcm80211/brcmsmac/dma.c
Normal file
File diff suppressed because it is too large
Load Diff
120
drivers/net/wireless/brcm80211/brcmsmac/dma.h
Normal file
120
drivers/net/wireless/brcm80211/brcmsmac/dma.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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_DMA_H_
|
||||
#define _BRCM_DMA_H_
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include "types.h" /* forward structure declarations */
|
||||
|
||||
/* map/unmap direction */
|
||||
#define DMA_TX 1 /* TX direction for DMA */
|
||||
#define DMA_RX 2 /* RX direction for DMA */
|
||||
|
||||
/* DMA structure:
|
||||
* support two DMA engines: 32 bits address or 64 bit addressing
|
||||
* basic DMA register set is per channel(transmit or receive)
|
||||
* a pair of channels is defined for convenience
|
||||
*/
|
||||
|
||||
/* 32 bits addressing */
|
||||
|
||||
struct dma32diag { /* diag access */
|
||||
u32 fifoaddr; /* diag address */
|
||||
u32 fifodatalow; /* low 32bits of data */
|
||||
u32 fifodatahigh; /* high 32bits of data */
|
||||
u32 pad; /* reserved */
|
||||
};
|
||||
|
||||
/* 64 bits addressing */
|
||||
|
||||
/* dma registers per channel(xmt or rcv) */
|
||||
struct dma64regs {
|
||||
u32 control; /* enable, et al */
|
||||
u32 ptr; /* last descriptor posted to chip */
|
||||
u32 addrlow; /* desc ring base address low 32-bits (8K aligned) */
|
||||
u32 addrhigh; /* desc ring base address bits 63:32 (8K aligned) */
|
||||
u32 status0; /* current descriptor, xmt state */
|
||||
u32 status1; /* active descriptor, xmt error */
|
||||
};
|
||||
|
||||
/* range param for dma_getnexttxp() and dma_txreclaim */
|
||||
enum txd_range {
|
||||
DMA_RANGE_ALL = 1,
|
||||
DMA_RANGE_TRANSMITTED,
|
||||
DMA_RANGE_TRANSFERED
|
||||
};
|
||||
|
||||
/*
|
||||
* Exported data structure (read-only)
|
||||
*/
|
||||
/* export structure */
|
||||
struct dma_pub {
|
||||
uint txavail; /* # free tx descriptors */
|
||||
uint dmactrlflags; /* dma control flags */
|
||||
|
||||
/* rx error counters */
|
||||
uint rxgiants; /* rx giant frames */
|
||||
uint rxnobuf; /* rx out of dma descriptors */
|
||||
/* tx error counters */
|
||||
uint txnobuf; /* tx out of dma descriptors */
|
||||
};
|
||||
|
||||
extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
|
||||
void __iomem *dmaregstx, void __iomem *dmaregsrx,
|
||||
uint ntxd, uint nrxd,
|
||||
uint rxbufsize, int rxextheadroom,
|
||||
uint nrxpost, uint rxoffset, uint *msg_level);
|
||||
|
||||
void dma_rxinit(struct dma_pub *pub);
|
||||
struct sk_buff *dma_rx(struct dma_pub *pub);
|
||||
bool dma_rxfill(struct dma_pub *pub);
|
||||
bool dma_rxreset(struct dma_pub *pub);
|
||||
bool dma_txreset(struct dma_pub *pub);
|
||||
void dma_txinit(struct dma_pub *pub);
|
||||
int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit);
|
||||
void dma_txsuspend(struct dma_pub *pub);
|
||||
bool dma_txsuspended(struct dma_pub *pub);
|
||||
void dma_txresume(struct dma_pub *pub);
|
||||
void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
|
||||
void dma_rxreclaim(struct dma_pub *pub);
|
||||
void dma_detach(struct dma_pub *pub);
|
||||
unsigned long dma_getvar(struct dma_pub *pub, const char *name);
|
||||
struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);
|
||||
void dma_counterreset(struct dma_pub *pub);
|
||||
|
||||
void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
|
||||
(void *pkt, void *arg_a), void *arg_a);
|
||||
|
||||
/*
|
||||
* DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but
|
||||
* the packet length is not updated yet (by DMA) on the expected time.
|
||||
* Workaround is to hold processor till DMA updates the length, and stay off
|
||||
* the bus to allow DMA update the length in buffer
|
||||
*/
|
||||
static inline void dma_spin_for_len(uint len, struct sk_buff *head)
|
||||
{
|
||||
#if defined(CONFIG_BCM47XX)
|
||||
if (!len) {
|
||||
while (!(len = *(u16 *) KSEG1ADDR(head->data)))
|
||||
udelay(1);
|
||||
|
||||
*(u16 *) (head->data) = cpu_to_le16((u16) len);
|
||||
}
|
||||
#endif /* defined(CONFIG_BCM47XX) */
|
||||
}
|
||||
|
||||
#endif /* _BRCM_DMA_H_ */
|
1701
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
Normal file
1701
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
Normal file
File diff suppressed because it is too large
Load Diff
107
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
Normal file
107
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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_MAC80211_IF_H_
|
||||
#define _BRCM_MAC80211_IF_H_
|
||||
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include "ucode_loader.h"
|
||||
/*
|
||||
* Starting index for 5G rates in the
|
||||
* legacy rate table.
|
||||
*/
|
||||
#define BRCMS_LEGACY_5G_RATE_OFFSET 4
|
||||
|
||||
/* softmac ioctl definitions */
|
||||
#define BRCMS_SET_SHORTSLOT_OVERRIDE 146
|
||||
|
||||
struct brcms_timer {
|
||||
struct timer_list timer;
|
||||
struct brcms_info *wl;
|
||||
void (*fn) (void *);
|
||||
void *arg; /* argument to fn */
|
||||
uint ms;
|
||||
bool periodic;
|
||||
bool set;
|
||||
struct brcms_timer *next;
|
||||
#ifdef BCMDBG
|
||||
char *name; /* Description of the timer */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct brcms_if {
|
||||
uint subunit; /* WDS/BSS unit */
|
||||
struct pci_dev *pci_dev;
|
||||
};
|
||||
|
||||
#define MAX_FW_IMAGES 4
|
||||
struct brcms_firmware {
|
||||
u32 fw_cnt;
|
||||
const struct firmware *fw_bin[MAX_FW_IMAGES];
|
||||
const struct firmware *fw_hdr[MAX_FW_IMAGES];
|
||||
u32 hdr_num_entries[MAX_FW_IMAGES];
|
||||
};
|
||||
|
||||
struct brcms_info {
|
||||
struct brcms_pub *pub; /* pointer to public wlc state */
|
||||
struct brcms_c_info *wlc; /* pointer to private common data */
|
||||
u32 magic;
|
||||
|
||||
int irq;
|
||||
|
||||
spinlock_t lock; /* per-device perimeter lock */
|
||||
spinlock_t isr_lock; /* per-device ISR synchronization lock */
|
||||
|
||||
/* regsva for unmap in brcms_free() */
|
||||
void __iomem *regsva; /* opaque chip registers virtual address */
|
||||
|
||||
/* timer related fields */
|
||||
atomic_t callbacks; /* # outstanding callback functions */
|
||||
struct brcms_timer *timers; /* timer cleanup queue */
|
||||
|
||||
struct tasklet_struct tasklet; /* dpc tasklet */
|
||||
bool resched; /* dpc needs to be and is rescheduled */
|
||||
struct brcms_firmware fw;
|
||||
struct wiphy *wiphy;
|
||||
struct brcms_ucode ucode;
|
||||
};
|
||||
|
||||
/* misc callbacks */
|
||||
extern void brcms_init(struct brcms_info *wl);
|
||||
extern uint brcms_reset(struct brcms_info *wl);
|
||||
extern void brcms_intrson(struct brcms_info *wl);
|
||||
extern u32 brcms_intrsoff(struct brcms_info *wl);
|
||||
extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
|
||||
extern int brcms_up(struct brcms_info *wl);
|
||||
extern void brcms_down(struct brcms_info *wl);
|
||||
extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
|
||||
bool state, int prio);
|
||||
extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
|
||||
|
||||
/* timer functions */
|
||||
extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
|
||||
void (*fn) (void *arg), void *arg,
|
||||
const char *name);
|
||||
extern void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *timer);
|
||||
extern void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *timer,
|
||||
uint ms, int periodic);
|
||||
extern bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *timer);
|
||||
extern void brcms_msleep(struct brcms_info *wl, uint ms);
|
||||
extern void brcms_dpc(unsigned long data);
|
||||
extern void brcms_timer(struct brcms_timer *t);
|
||||
|
||||
#endif /* _BRCM_MAC80211_IF_H_ */
|
8841
drivers/net/wireless/brcm80211/brcmsmac/main.c
Normal file
8841
drivers/net/wireless/brcm80211/brcmsmac/main.c
Normal file
File diff suppressed because it is too large
Load Diff
819
drivers/net/wireless/brcm80211/brcmsmac/main.h
Normal file
819
drivers/net/wireless/brcm80211/brcmsmac/main.h
Normal file
@ -0,0 +1,819 @@
|
||||
/*
|
||||
* 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_MAIN_H_
|
||||
#define _BRCM_MAIN_H_
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include "types.h"
|
||||
#include "d11.h"
|
||||
#include "scb.h"
|
||||
|
||||
#define INVCHANNEL 255 /* invalid channel */
|
||||
|
||||
/* max # brcms_c_module_register() calls */
|
||||
#define BRCMS_MAXMODULES 22
|
||||
|
||||
#define SEQNUM_SHIFT 4
|
||||
#define SEQNUM_MAX 0x1000
|
||||
|
||||
#define NTXRATE 64 /* # tx MPDUs rate is reported for */
|
||||
|
||||
/* Maximum wait time for a MAC suspend */
|
||||
/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
|
||||
#define BRCMS_MAX_MAC_SUSPEND 83000
|
||||
|
||||
/* responses for probe requests older that this are tossed, zero to disable */
|
||||
#define BRCMS_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */
|
||||
|
||||
/* transmit buffer max headroom for protocol headers */
|
||||
#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
|
||||
|
||||
#define AC_COUNT 4
|
||||
|
||||
/* Macros for doing definition and get/set of bitfields
|
||||
* Usage example, e.g. a three-bit field (bits 4-6):
|
||||
* #define <NAME>_M BITFIELD_MASK(3)
|
||||
* #define <NAME>_S 4
|
||||
* ...
|
||||
* regval = R_REG(osh, ®s->regfoo);
|
||||
* field = GFIELD(regval, <NAME>);
|
||||
* regval = SFIELD(regval, <NAME>, 1);
|
||||
* W_REG(osh, ®s->regfoo, regval);
|
||||
*/
|
||||
#define BITFIELD_MASK(width) \
|
||||
(((unsigned)1 << (width)) - 1)
|
||||
#define GFIELD(val, field) \
|
||||
(((val) >> field ## _S) & field ## _M)
|
||||
#define SFIELD(val, field, bits) \
|
||||
(((val) & (~(field ## _M << field ## _S))) | \
|
||||
((unsigned)(bits) << field ## _S))
|
||||
|
||||
#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */
|
||||
|
||||
/* max # supported core revisions (0 .. MAXCOREREV - 1) */
|
||||
#define MAXCOREREV 28
|
||||
|
||||
/* Double check that unsupported cores are not enabled */
|
||||
#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
|
||||
#error "Configuration for D11CONF includes unsupported versions."
|
||||
#endif /* Bad versions */
|
||||
|
||||
/* values for shortslot_override */
|
||||
#define BRCMS_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */
|
||||
#define BRCMS_SHORTSLOT_OFF 0 /* Turn off short slot */
|
||||
#define BRCMS_SHORTSLOT_ON 1 /* Turn on short slot */
|
||||
|
||||
/* value for short/long and mixmode/greenfield preamble */
|
||||
#define BRCMS_LONG_PREAMBLE (0)
|
||||
#define BRCMS_SHORT_PREAMBLE (1 << 0)
|
||||
#define BRCMS_GF_PREAMBLE (1 << 1)
|
||||
#define BRCMS_MM_PREAMBLE (1 << 2)
|
||||
#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \
|
||||
((_pre) == BRCMS_MM_PREAMBLE))
|
||||
|
||||
/* TxFrameID */
|
||||
/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
|
||||
/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
|
||||
#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */
|
||||
#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */
|
||||
#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */
|
||||
#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */
|
||||
#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */
|
||||
#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */
|
||||
|
||||
/* promote boardrev */
|
||||
#define BOARDREV_PROMOTABLE 0xFF /* from */
|
||||
#define BOARDREV_PROMOTED 1 /* to */
|
||||
|
||||
#define DATA_BLOCK_TX_SUPR (1 << 4)
|
||||
|
||||
/* 802.1D Priority to TX FIFO number for wme */
|
||||
extern const u8 prio2fifo[];
|
||||
|
||||
/* Ucode MCTL_WAKE override bits */
|
||||
#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01
|
||||
#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02
|
||||
#define BRCMS_WAKE_OVERRIDE_MACSUSPEND 0x04
|
||||
#define BRCMS_WAKE_OVERRIDE_TXFIFO 0x08
|
||||
#define BRCMS_WAKE_OVERRIDE_FORCEFAST 0x10
|
||||
|
||||
/* stuff pulled in from wlc.c */
|
||||
|
||||
/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other
|
||||
* times; and if we run out, constant I_RU interrupts may cause lockup. We
|
||||
* will still get error counts from rx0ovfl.
|
||||
*/
|
||||
#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU)
|
||||
/* default software intmasks */
|
||||
#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */
|
||||
#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
|
||||
MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
|
||||
MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
|
||||
|
||||
#define MAXTXPKTS 6 /* max # pkts pending */
|
||||
|
||||
/* frameburst */
|
||||
#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */
|
||||
#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */
|
||||
|
||||
#define NFIFO 6 /* # tx/rx fifopairs */
|
||||
|
||||
/* PLL requests */
|
||||
|
||||
/* pll is shared on old chips */
|
||||
#define BRCMS_PLLREQ_SHARED 0x1
|
||||
/* hold pll for radio monitor register checking */
|
||||
#define BRCMS_PLLREQ_RADIO_MON 0x2
|
||||
/* hold/release pll for some short operation */
|
||||
#define BRCMS_PLLREQ_FLIP 0x4
|
||||
|
||||
#define CHANNEL_BANDUNIT(wlc, ch) \
|
||||
(((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
|
||||
|
||||
#define OTHERBANDUNIT(wlc) \
|
||||
((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
|
||||
|
||||
/*
|
||||
* 802.11 protection information
|
||||
*
|
||||
* _g: use g spec protection, driver internal.
|
||||
* g_override: override for use of g spec protection.
|
||||
* gmode_user: user config gmode, operating band->gmode is different.
|
||||
* overlap: Overlap BSS/IBSS protection for both 11g and 11n.
|
||||
* nmode_user: user config nmode, operating pub->nmode is different.
|
||||
* n_cfg: use OFDM protection on MIMO frames.
|
||||
* n_cfg_override: override for use of N protection.
|
||||
* nongf: non-GF present protection.
|
||||
* nongf_override: override for use of GF protection.
|
||||
* n_pam_override: override for preamble: MM or GF.
|
||||
* n_obss: indicated OBSS Non-HT STA present.
|
||||
*/
|
||||
struct brcms_protection {
|
||||
bool _g;
|
||||
s8 g_override;
|
||||
u8 gmode_user;
|
||||
s8 overlap;
|
||||
s8 nmode_user;
|
||||
s8 n_cfg;
|
||||
s8 n_cfg_override;
|
||||
bool nongf;
|
||||
s8 nongf_override;
|
||||
s8 n_pam_override;
|
||||
bool n_obss;
|
||||
};
|
||||
|
||||
/*
|
||||
* anything affecting the single/dual streams/antenna operation
|
||||
*
|
||||
* hw_txchain: HW txchain bitmap cfg.
|
||||
* txchain: txchain bitmap being used.
|
||||
* txstreams: number of txchains being used.
|
||||
* hw_rxchain: HW rxchain bitmap cfg.
|
||||
* rxchain: rxchain bitmap being used.
|
||||
* rxstreams: number of rxchains being used.
|
||||
* ant_rx_ovr: rx antenna override.
|
||||
* txant: userTx antenna setting.
|
||||
* phytxant: phyTx antenna setting in txheader.
|
||||
* ss_opmode: singlestream Operational mode, 0:siso; 1:cdd.
|
||||
* ss_algosel_auto: if true, use wlc->stf->ss_algo_channel;
|
||||
* else use wlc->band->stf->ss_mode_band.
|
||||
* ss_algo_channel: ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC.
|
||||
* rxchain_restore_delay: delay time to restore default rxchain.
|
||||
* ldpc: AUTO/ON/OFF ldpc cap supported.
|
||||
* txcore[MAX_STREAMS_SUPPORTED + 1]: bitmap of selected core for each Nsts.
|
||||
* spatial_policy:
|
||||
*/
|
||||
struct brcms_stf {
|
||||
u8 hw_txchain;
|
||||
u8 txchain;
|
||||
u8 txstreams;
|
||||
u8 hw_rxchain;
|
||||
u8 rxchain;
|
||||
u8 rxstreams;
|
||||
u8 ant_rx_ovr;
|
||||
s8 txant;
|
||||
u16 phytxant;
|
||||
u8 ss_opmode;
|
||||
bool ss_algosel_auto;
|
||||
u16 ss_algo_channel;
|
||||
u8 rxchain_restore_delay;
|
||||
s8 ldpc;
|
||||
u8 txcore[MAX_STREAMS_SUPPORTED + 1];
|
||||
s8 spatial_policy;
|
||||
};
|
||||
|
||||
#define BRCMS_STF_SS_STBC_TX(wlc, scb) \
|
||||
(((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) \
|
||||
|| (((scb)->flags & SCB_STBCCAP) && \
|
||||
(wlc)->band->band_stf_stbc_tx == AUTO && \
|
||||
isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
|
||||
|
||||
#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GE(wlc->band->phyrev, 3))
|
||||
|
||||
#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GE(wlc->band->phyrev, 3)) || \
|
||||
BRCMS_ISLCNPHY(wlc->band))
|
||||
|
||||
#define BRCMS_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) \
|
||||
>> RXS_CHAN_PHYTYPE_SHIFT)
|
||||
#define BRCMS_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) \
|
||||
>> RXS_CHAN_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* core state (mac)
|
||||
*/
|
||||
struct brcms_core {
|
||||
uint coreidx; /* # sb enumerated core */
|
||||
|
||||
/* fifo */
|
||||
uint *txavail[NFIFO]; /* # tx descriptors available */
|
||||
s16 txpktpend[NFIFO]; /* tx admission control */
|
||||
|
||||
struct macstat *macstat_snapshot; /* mac hw prev read values */
|
||||
};
|
||||
|
||||
/*
|
||||
* band state (phy+ana+radio)
|
||||
*/
|
||||
struct brcms_band {
|
||||
int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
|
||||
uint bandunit; /* bandstate[] index */
|
||||
|
||||
u16 phytype; /* phytype */
|
||||
u16 phyrev;
|
||||
u16 radioid;
|
||||
u16 radiorev;
|
||||
struct brcms_phy_pub *pi; /* pointer to phy specific information */
|
||||
bool abgphy_encore;
|
||||
|
||||
u8 gmode; /* currently active gmode */
|
||||
|
||||
struct scb *hwrs_scb; /* permanent scb for hw rateset */
|
||||
|
||||
/* band-specific copy of default_bss.rateset */
|
||||
struct brcms_c_rateset defrateset;
|
||||
|
||||
u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */
|
||||
s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */
|
||||
/* rates supported by chip (phy-specific) */
|
||||
struct brcms_c_rateset hw_rateset;
|
||||
u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */
|
||||
bool mimo_cap_40; /* 40 MHz cap enabled on this band */
|
||||
s8 antgain; /* antenna gain from srom */
|
||||
|
||||
u16 CWmin; /* minimum size of contention window, in unit of aSlotTime */
|
||||
u16 CWmax; /* maximum size of contention window, in unit of aSlotTime */
|
||||
struct ieee80211_supported_band band;
|
||||
};
|
||||
|
||||
/* module control blocks */
|
||||
struct modulecb {
|
||||
/* module name : NULL indicates empty array member */
|
||||
char name[32];
|
||||
/* handle passed when handler 'doiovar' is called */
|
||||
struct brcms_info *hdl;
|
||||
|
||||
int (*down_fn)(void *handle); /* down handler. Note: the int returned
|
||||
* by the down function is a count of the
|
||||
* number of timers that could not be
|
||||
* freed.
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
struct brcms_hw_band {
|
||||
int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
|
||||
uint bandunit; /* bandstate[] index */
|
||||
u16 mhfs[MHFMAX]; /* MHF array shadow */
|
||||
u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */
|
||||
u16 CWmin;
|
||||
u16 CWmax;
|
||||
u32 core_flags;
|
||||
|
||||
u16 phytype; /* phytype */
|
||||
u16 phyrev;
|
||||
u16 radioid;
|
||||
u16 radiorev;
|
||||
struct brcms_phy_pub *pi; /* pointer to phy specific information */
|
||||
bool abgphy_encore;
|
||||
};
|
||||
|
||||
struct brcms_hardware {
|
||||
bool _piomode; /* true if pio mode */
|
||||
struct brcms_c_info *wlc;
|
||||
|
||||
/* fifo */
|
||||
struct dma_pub *di[NFIFO]; /* dma handles, per fifo */
|
||||
|
||||
uint unit; /* device instance number */
|
||||
|
||||
/* version info */
|
||||
u16 vendorid; /* PCI vendor id */
|
||||
u16 deviceid; /* PCI device id */
|
||||
uint corerev; /* core revision */
|
||||
u8 sromrev; /* version # of the srom */
|
||||
u16 boardrev; /* version # of particular board */
|
||||
u32 boardflags; /* Board specific flags from srom */
|
||||
u32 boardflags2; /* More board flags if sromrev >= 4 */
|
||||
u32 machwcap; /* MAC capabilities */
|
||||
u32 machwcap_backup; /* backup of machwcap */
|
||||
|
||||
struct si_pub *sih; /* SI handle (cookie for siutils calls) */
|
||||
struct d11regs __iomem *regs; /* pointer to device registers */
|
||||
struct phy_shim_info *physhim; /* phy shim layer handler */
|
||||
struct shared_phy *phy_sh; /* pointer to shared phy state */
|
||||
struct brcms_hw_band *band;/* pointer to active per-band state */
|
||||
/* band state per phy/radio */
|
||||
struct brcms_hw_band *bandstate[MAXBANDS];
|
||||
u16 bmac_phytxant; /* cache of high phytxant state */
|
||||
bool shortslot; /* currently using 11g ShortSlot timing */
|
||||
u16 SRL; /* 802.11 dot11ShortRetryLimit */
|
||||
u16 LRL; /* 802.11 dot11LongRetryLimit */
|
||||
u16 SFBL; /* Short Frame Rate Fallback Limit */
|
||||
u16 LFBL; /* Long Frame Rate Fallback Limit */
|
||||
|
||||
bool up; /* d11 hardware up and running */
|
||||
uint now; /* # elapsed seconds */
|
||||
uint _nbands; /* # bands supported */
|
||||
u16 chanspec; /* bmac chanspec shadow */
|
||||
|
||||
uint *txavail[NFIFO]; /* # tx descriptors available */
|
||||
const u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */
|
||||
|
||||
u32 pllreq; /* pll requests to keep PLL on */
|
||||
|
||||
u8 suspended_fifos; /* Which TX fifo to remain awake for */
|
||||
u32 maccontrol; /* Cached value of maccontrol */
|
||||
uint mac_suspend_depth; /* current depth of mac_suspend levels */
|
||||
u32 wake_override; /* bit flags to force MAC to WAKE mode */
|
||||
u32 mute_override; /* Prevent ucode from sending beacons */
|
||||
u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */
|
||||
bool noreset; /* true= do not reset hw, used by WLC_OUT */
|
||||
bool forcefastclk; /* true if h/w is forcing to use fast clk */
|
||||
bool clk; /* core is out of reset and has clock */
|
||||
bool sbclk; /* sb has clock */
|
||||
bool phyclk; /* phy is out of reset and has clock */
|
||||
|
||||
bool ucode_loaded; /* true after ucode downloaded */
|
||||
|
||||
|
||||
u8 hw_stf_ss_opmode; /* STF single stream operation mode */
|
||||
u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
|
||||
* 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
|
||||
*/
|
||||
u32 antsel_avail; /*
|
||||
* put struct antsel_info here if more info is
|
||||
* needed
|
||||
*/
|
||||
};
|
||||
|
||||
/* TX Queue information
|
||||
*
|
||||
* Each flow of traffic out of the device has a TX Queue with independent
|
||||
* flow control. Several interfaces may be associated with a single TX Queue
|
||||
* if they belong to the same flow of traffic from the device. For multi-channel
|
||||
* operation there are independent TX Queues for each channel.
|
||||
*/
|
||||
struct brcms_txq_info {
|
||||
struct brcms_txq_info *next;
|
||||
struct pktq q;
|
||||
uint stopped; /* tx flow control bits */
|
||||
};
|
||||
|
||||
/*
|
||||
* Principal common driver data structure.
|
||||
*
|
||||
* pub: pointer to driver public state.
|
||||
* wl: pointer to specific private state.
|
||||
* regs: pointer to device registers.
|
||||
* hw: HW related state.
|
||||
* clkreq_override: setting for clkreq for PCIE : Auto, 0, 1.
|
||||
* fastpwrup_dly: time in us needed to bring up d11 fast clock.
|
||||
* macintstatus: bit channel between isr and dpc.
|
||||
* macintmask: sw runtime master macintmask value.
|
||||
* defmacintmask: default "on" macintmask value.
|
||||
* clk: core is out of reset and has clock.
|
||||
* core: pointer to active io core.
|
||||
* band: pointer to active per-band state.
|
||||
* corestate: per-core state (one per hw core).
|
||||
* bandstate: per-band state (one per phy/radio).
|
||||
* qvalid: DirFrmQValid and BcMcFrmQValid.
|
||||
* ampdu: ampdu module handler.
|
||||
* asi: antsel module handler.
|
||||
* cmi: channel manager module handler.
|
||||
* vendorid: PCI vendor id.
|
||||
* deviceid: PCI device id.
|
||||
* ucode_rev: microcode revision.
|
||||
* machwcap: MAC capabilities, BMAC shadow.
|
||||
* perm_etheraddr: original sprom local ethernet address.
|
||||
* bandlocked: disable auto multi-band switching.
|
||||
* bandinit_pending: track band init in auto band.
|
||||
* radio_monitor: radio timer is running.
|
||||
* going_down: down path intermediate variable.
|
||||
* mpc: enable minimum power consumption.
|
||||
* mpc_dlycnt: # of watchdog cnt before turn disable radio.
|
||||
* mpc_offcnt: # of watchdog cnt that radio is disabled.
|
||||
* mpc_delay_off: delay radio disable by # of watchdog cnt.
|
||||
* prev_non_delay_mpc: prev state brcms_c_is_non_delay_mpc.
|
||||
* wdtimer: timer for watchdog routine.
|
||||
* radio_timer: timer for hw radio button monitor routine.
|
||||
* monitor: monitor (MPDU sniffing) mode.
|
||||
* bcnmisc_monitor: bcns promisc mode override for monitor.
|
||||
* _rifs: enable per-packet rifs.
|
||||
* bcn_li_bcn: beacon listen interval in # beacons.
|
||||
* bcn_li_dtim: beacon listen interval in # dtims.
|
||||
* WDarmed: watchdog timer is armed.
|
||||
* WDlast: last time wlc_watchdog() was called.
|
||||
* edcf_txop[AC_COUNT]: current txop for each ac.
|
||||
* wme_retries: per-AC retry limits.
|
||||
* tx_prec_map: Precedence map based on HW FIFO space.
|
||||
* fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.
|
||||
* bsscfg: set of BSS configurations, idx 0 is default and always valid.
|
||||
* cfg: the primary bsscfg (can be AP or STA).
|
||||
* tx_queues: common TX Queue list.
|
||||
* modulecb:
|
||||
* mimoft: SIGN or 11N.
|
||||
* cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
|
||||
* ofdm_40txbw: 11N, ofdm tx b/w override when in 40MHZ mode.
|
||||
* mimo_40txbw: 11N, mimo tx b/w override when in 40MHZ mode.
|
||||
* default_bss: configured BSS parameters.
|
||||
* mc_fid_counter: BC/MC FIFO frame ID counter.
|
||||
* country_default: saved country for leaving 802.11d auto-country mode.
|
||||
* autocountry_default: initial country for 802.11d auto-country mode.
|
||||
* prb_resp_timeout: do not send prb resp if request older
|
||||
* than this, 0 = disable.
|
||||
* home_chanspec: shared home chanspec.
|
||||
* chanspec: target operational channel.
|
||||
* usr_fragthresh: user configured fragmentation threshold.
|
||||
* fragthresh[NFIFO]: per-fifo fragmentation thresholds.
|
||||
* RTSThresh: 802.11 dot11RTSThreshold.
|
||||
* SRL: 802.11 dot11ShortRetryLimit.
|
||||
* LRL: 802.11 dot11LongRetryLimit.
|
||||
* SFBL: Short Frame Rate Fallback Limit.
|
||||
* LFBL: Long Frame Rate Fallback Limit.
|
||||
* shortslot: currently using 11g ShortSlot timing.
|
||||
* shortslot_override: 11g ShortSlot override.
|
||||
* include_legacy_erp: include Legacy ERP info elt ID 47 as well as g ID 42.
|
||||
* PLCPHdr_override: 802.11b Preamble Type override.
|
||||
* stf:
|
||||
* bcn_rspec: save bcn ratespec purpose.
|
||||
* tempsense_lasttime;
|
||||
* tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
|
||||
* tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
|
||||
* pkt_queue: txq for transmit packets.
|
||||
* wiphy:
|
||||
* pri_scb: primary Station Control Block
|
||||
*/
|
||||
struct brcms_c_info {
|
||||
struct brcms_pub *pub;
|
||||
struct brcms_info *wl;
|
||||
struct d11regs __iomem *regs;
|
||||
struct brcms_hardware *hw;
|
||||
|
||||
/* clock */
|
||||
u16 fastpwrup_dly;
|
||||
|
||||
/* interrupt */
|
||||
u32 macintstatus;
|
||||
u32 macintmask;
|
||||
u32 defmacintmask;
|
||||
|
||||
bool clk;
|
||||
|
||||
/* multiband */
|
||||
struct brcms_core *core;
|
||||
struct brcms_band *band;
|
||||
struct brcms_core *corestate;
|
||||
struct brcms_band *bandstate[MAXBANDS];
|
||||
|
||||
/* packet queue */
|
||||
uint qvalid;
|
||||
|
||||
struct ampdu_info *ampdu;
|
||||
struct antsel_info *asi;
|
||||
struct brcms_cm_info *cmi;
|
||||
|
||||
u16 vendorid;
|
||||
u16 deviceid;
|
||||
uint ucode_rev;
|
||||
|
||||
u8 perm_etheraddr[ETH_ALEN];
|
||||
|
||||
bool bandlocked;
|
||||
bool bandinit_pending;
|
||||
|
||||
bool radio_monitor;
|
||||
bool going_down;
|
||||
|
||||
bool mpc;
|
||||
u8 mpc_dlycnt;
|
||||
u8 mpc_offcnt;
|
||||
u8 mpc_delay_off;
|
||||
u8 prev_non_delay_mpc;
|
||||
|
||||
struct brcms_timer *wdtimer;
|
||||
struct brcms_timer *radio_timer;
|
||||
|
||||
/* promiscuous */
|
||||
bool monitor;
|
||||
bool bcnmisc_monitor;
|
||||
|
||||
/* driver feature */
|
||||
bool _rifs;
|
||||
|
||||
/* AP-STA synchronization, power save */
|
||||
u8 bcn_li_bcn;
|
||||
u8 bcn_li_dtim;
|
||||
|
||||
bool WDarmed;
|
||||
u32 WDlast;
|
||||
|
||||
/* WME */
|
||||
u16 edcf_txop[AC_COUNT];
|
||||
|
||||
u16 wme_retries[AC_COUNT];
|
||||
u16 tx_prec_map;
|
||||
u16 fifo2prec_map[NFIFO];
|
||||
|
||||
struct brcms_bss_cfg *bsscfg;
|
||||
|
||||
/* tx queue */
|
||||
struct brcms_txq_info *tx_queues;
|
||||
|
||||
struct modulecb *modulecb;
|
||||
|
||||
u8 mimoft;
|
||||
s8 cck_40txbw;
|
||||
s8 ofdm_40txbw;
|
||||
s8 mimo_40txbw;
|
||||
|
||||
struct brcms_bss_info *default_bss;
|
||||
|
||||
u16 mc_fid_counter;
|
||||
|
||||
char country_default[BRCM_CNTRY_BUF_SZ];
|
||||
char autocountry_default[BRCM_CNTRY_BUF_SZ];
|
||||
u16 prb_resp_timeout;
|
||||
|
||||
u16 home_chanspec;
|
||||
|
||||
/* PHY parameters */
|
||||
u16 chanspec;
|
||||
u16 usr_fragthresh;
|
||||
u16 fragthresh[NFIFO];
|
||||
u16 RTSThresh;
|
||||
u16 SRL;
|
||||
u16 LRL;
|
||||
u16 SFBL;
|
||||
u16 LFBL;
|
||||
|
||||
/* network config */
|
||||
bool shortslot;
|
||||
s8 shortslot_override;
|
||||
bool include_legacy_erp;
|
||||
|
||||
struct brcms_protection *protection;
|
||||
s8 PLCPHdr_override;
|
||||
|
||||
struct brcms_stf *stf;
|
||||
|
||||
u32 bcn_rspec;
|
||||
|
||||
uint tempsense_lasttime;
|
||||
|
||||
u16 tx_duty_cycle_ofdm;
|
||||
u16 tx_duty_cycle_cck;
|
||||
|
||||
struct brcms_txq_info *pkt_queue;
|
||||
struct wiphy *wiphy;
|
||||
struct scb pri_scb;
|
||||
};
|
||||
|
||||
/* antsel module specific state */
|
||||
struct antsel_info {
|
||||
struct brcms_c_info *wlc; /* pointer to main wlc structure */
|
||||
struct brcms_pub *pub; /* pointer to public fn */
|
||||
u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
|
||||
* 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
|
||||
*/
|
||||
u8 antsel_antswitch; /* board level antenna switch type */
|
||||
bool antsel_avail; /* Ant selection availability (SROM based) */
|
||||
struct brcms_antselcfg antcfg_11n; /* antenna configuration */
|
||||
struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
|
||||
};
|
||||
|
||||
/*
|
||||
* BSS configuration state
|
||||
*
|
||||
* wlc: wlc to which this bsscfg belongs to.
|
||||
* up: is this configuration up operational
|
||||
* enable: is this configuration enabled
|
||||
* associated: is BSS in ASSOCIATED state
|
||||
* BSS: infraustructure or adhoc
|
||||
* SSID_len: the length of SSID
|
||||
* SSID: SSID string
|
||||
*
|
||||
*
|
||||
* BSSID: BSSID (associated)
|
||||
* cur_etheraddr: h/w address
|
||||
* flags: BSSCFG flags; see below
|
||||
*
|
||||
* current_bss: BSS parms in ASSOCIATED state
|
||||
*
|
||||
*
|
||||
* ID: 'unique' ID of this bsscfg, assigned at bsscfg allocation
|
||||
*/
|
||||
struct brcms_bss_cfg {
|
||||
struct brcms_c_info *wlc;
|
||||
bool up;
|
||||
bool enable;
|
||||
bool associated;
|
||||
bool BSS;
|
||||
u8 SSID_len;
|
||||
u8 SSID[IEEE80211_MAX_SSID_LEN];
|
||||
u8 BSSID[ETH_ALEN];
|
||||
u8 cur_etheraddr[ETH_ALEN];
|
||||
struct brcms_bss_info *current_bss;
|
||||
};
|
||||
|
||||
extern void brcms_c_fatal_error(struct brcms_c_info *wlc);
|
||||
extern void brcms_b_rpc_watchdog(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p);
|
||||
extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
|
||||
struct sk_buff *p,
|
||||
bool commit, s8 txpktpend);
|
||||
extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
|
||||
s8 txpktpend);
|
||||
extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
|
||||
struct sk_buff *sdu, uint prec);
|
||||
extern void brcms_c_info_init(struct brcms_c_info *wlc, int unit);
|
||||
extern void brcms_c_print_txstatus(struct tx_status *txs);
|
||||
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
|
||||
uint *blocks);
|
||||
|
||||
#if defined(BCMDBG)
|
||||
extern void brcms_c_print_rxh(struct d11rxhdr *rxh);
|
||||
extern void brcms_c_print_txdesc(struct d11txh *txh);
|
||||
#else
|
||||
#define brcms_c_print_txdesc(a)
|
||||
#endif
|
||||
|
||||
extern void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit);
|
||||
extern void brcms_c_coredisable(struct brcms_hardware *wlc_hw);
|
||||
|
||||
extern bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rate,
|
||||
int band, bool verbose);
|
||||
extern void brcms_c_ap_upd(struct brcms_c_info *wlc);
|
||||
|
||||
/* helper functions */
|
||||
extern void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc,
|
||||
struct brcms_bss_cfg *cfg);
|
||||
extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
|
||||
|
||||
extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
|
||||
bool promisc);
|
||||
extern void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_mac_promisc(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_txflowcontrol(struct brcms_c_info *wlc,
|
||||
struct brcms_txq_info *qi,
|
||||
bool on, int prio);
|
||||
extern void brcms_c_txflowcontrol_override(struct brcms_c_info *wlc,
|
||||
struct brcms_txq_info *qi,
|
||||
bool on, uint override);
|
||||
extern bool brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc,
|
||||
struct brcms_txq_info *qi,
|
||||
int prio);
|
||||
extern void brcms_c_send_q(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
|
||||
uint *fifo);
|
||||
|
||||
extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
|
||||
uint mac_len);
|
||||
extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
|
||||
u32 rspec,
|
||||
bool use_rspec, u16 mimo_ctlchbw);
|
||||
extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
|
||||
u32 rts_rate,
|
||||
u32 frame_rate,
|
||||
u8 rts_preamble_type,
|
||||
u8 frame_preamble_type, uint frame_len,
|
||||
bool ba);
|
||||
|
||||
extern void brcms_c_tbtt(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
void (*dma_callback_fn));
|
||||
|
||||
/* Shared memory access */
|
||||
extern void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
|
||||
const void *buf, int len);
|
||||
|
||||
extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
|
||||
extern void brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
|
||||
struct brcms_bss_cfg *cfg,
|
||||
bool suspend);
|
||||
extern bool brcms_c_ismpc(struct brcms_c_info *wlc);
|
||||
extern bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc);
|
||||
extern bool brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
|
||||
struct sk_buff *pkt, int prec, bool head);
|
||||
extern u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec);
|
||||
extern void brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rate,
|
||||
uint length, u8 *plcp);
|
||||
extern uint brcms_c_calc_frame_time(struct brcms_c_info *wlc,
|
||||
u32 ratespec,
|
||||
u8 preamble_type, uint mac_len);
|
||||
|
||||
extern void brcms_c_set_chanspec(struct brcms_c_info *wlc,
|
||||
u16 chanspec);
|
||||
|
||||
extern bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit);
|
||||
|
||||
extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_mimops_action_ht_send(struct brcms_c_info *wlc,
|
||||
struct brcms_bss_cfg *bsscfg,
|
||||
u8 mimops_mode);
|
||||
|
||||
extern void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot);
|
||||
extern void brcms_c_set_bssid(struct brcms_bss_cfg *cfg);
|
||||
extern void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend);
|
||||
|
||||
extern void brcms_c_set_ratetable(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_set_mac(struct brcms_bss_cfg *cfg);
|
||||
extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
|
||||
u32 bcn_rate);
|
||||
extern void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc,
|
||||
uint frame_len);
|
||||
extern u32 brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc,
|
||||
struct brcms_c_rateset *rs);
|
||||
extern void brcms_c_radio_disable(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_bcn_li_upd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_set_home_chanspec(struct brcms_c_info *wlc,
|
||||
u16 chanspec);
|
||||
extern bool brcms_c_ps_allowed(struct brcms_c_info *wlc);
|
||||
extern bool brcms_c_stay_awake(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
|
||||
u8 antsel_type);
|
||||
|
||||
/* chanspec, ucode interface */
|
||||
extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
|
||||
u16 chanspec,
|
||||
bool mute, struct txpwr_limits *txpwr);
|
||||
|
||||
extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
|
||||
u16 v);
|
||||
extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
|
||||
|
||||
extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
|
||||
u16 val, int bands);
|
||||
|
||||
extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
|
||||
|
||||
extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
|
||||
|
||||
extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
|
||||
extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
|
||||
u32 override_bit);
|
||||
extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
|
||||
u32 override_bit);
|
||||
extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw,
|
||||
int offset, int len, void *buf);
|
||||
extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
|
||||
extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw,
|
||||
uint offset, const void *buf, int len,
|
||||
u32 sel);
|
||||
extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
|
||||
void *buf, int len, u32 sel);
|
||||
extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
|
||||
extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
|
||||
extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
|
||||
extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
|
||||
extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
|
||||
extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
|
||||
u8 stf_mode);
|
||||
extern void brcms_c_init_scb(struct scb *scb);
|
||||
|
||||
#endif /* _BRCM_MAIN_H_ */
|
835
drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
Normal file
835
drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
Normal file
@ -0,0 +1,835 @@
|
||||
/*
|
||||
* 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/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include <soc.h>
|
||||
#include <chipcommon.h>
|
||||
#include "aiutils.h"
|
||||
#include "pub.h"
|
||||
#include "nicpci.h"
|
||||
|
||||
/* SPROM offsets */
|
||||
#define SRSH_ASPM_OFFSET 4 /* word 4 */
|
||||
#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */
|
||||
#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */
|
||||
#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */
|
||||
|
||||
#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */
|
||||
#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */
|
||||
#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */
|
||||
#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */
|
||||
#define SRSH_BD_OFFSET 6 /* word 6 */
|
||||
|
||||
/* chipcontrol */
|
||||
#define CHIPCTRL_4321_PLL_DOWN 0x800000/* serdes PLL down override */
|
||||
|
||||
/* MDIO control */
|
||||
#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
|
||||
#define MDIOCTL_DIVISOR_VAL 0x2
|
||||
#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
|
||||
#define MDIOCTL_ACCESS_DONE 0x100 /* Transaction complete */
|
||||
|
||||
/* MDIO Data */
|
||||
#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
|
||||
#define MDIODATA_TA 0x00020000 /* Turnaround */
|
||||
|
||||
#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
|
||||
#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
|
||||
#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
|
||||
#define MDIODATA_DEVADDR_MASK 0x0f800000
|
||||
/* Physmedia devaddr Mask */
|
||||
|
||||
/* MDIO Data for older revisions < 10 */
|
||||
#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift */
|
||||
#define MDIODATA_REGADDR_MASK_OLD 0x003c0000
|
||||
/* Regaddr Mask */
|
||||
#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift */
|
||||
#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000
|
||||
/* Physmedia devaddr Mask */
|
||||
|
||||
/* Transactions flags */
|
||||
#define MDIODATA_WRITE 0x10000000
|
||||
#define MDIODATA_READ 0x20000000
|
||||
#define MDIODATA_START 0x40000000
|
||||
|
||||
#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
|
||||
#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
|
||||
|
||||
/* serdes regs (rev < 10) */
|
||||
#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
|
||||
#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
|
||||
#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
|
||||
|
||||
/* SERDES RX registers */
|
||||
#define SERDES_RX_CTRL 1 /* Rx cntrl */
|
||||
#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
|
||||
#define SERDES_RX_CDR 6 /* CDR */
|
||||
#define SERDES_RX_CDRBW 7 /* CDR BW */
|
||||
/* SERDES RX control register */
|
||||
#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
|
||||
#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
|
||||
|
||||
/* SERDES PLL registers */
|
||||
#define SERDES_PLL_CTRL 1 /* PLL control reg */
|
||||
#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
|
||||
|
||||
/* Linkcontrol reg offset in PCIE Cap */
|
||||
#define PCIE_CAP_LINKCTRL_OFFSET 16 /* offset in pcie cap */
|
||||
#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */
|
||||
#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */
|
||||
#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */
|
||||
|
||||
#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */
|
||||
|
||||
/* Power management threshold */
|
||||
#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */
|
||||
#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */
|
||||
#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */
|
||||
#define PCIE_ASPMTIMER_EXTEND 0x01000000
|
||||
/* > rev7:
|
||||
* enable extend ASPM timer
|
||||
*/
|
||||
|
||||
/* different register spaces to access thru pcie indirect access */
|
||||
#define PCIE_CONFIGREGS 1 /* Access to config space */
|
||||
#define PCIE_PCIEREGS 2 /* Access to pcie registers */
|
||||
|
||||
/* PCIE protocol PHY diagnostic registers */
|
||||
#define PCIE_PLP_STATUSREG 0x204 /* Status */
|
||||
|
||||
/* Status reg PCIE_PLP_STATUSREG */
|
||||
#define PCIE_PLP_POLARITYINV_STAT 0x10
|
||||
|
||||
/* PCIE protocol DLLP diagnostic registers */
|
||||
#define PCIE_DLLP_LCREG 0x100 /* Link Control */
|
||||
#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
|
||||
|
||||
/* PCIE protocol TLP diagnostic registers */
|
||||
#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
|
||||
|
||||
/* Sonics to PCI translation types */
|
||||
#define SBTOPCI_PREF 0x4 /* prefetch enable */
|
||||
#define SBTOPCI_BURST 0x8 /* burst enable */
|
||||
#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
|
||||
|
||||
#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */
|
||||
|
||||
/* PCI core index in SROM shadow area */
|
||||
#define SRSH_PI_OFFSET 0 /* first word */
|
||||
#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
|
||||
#define SRSH_PI_SHIFT 12 /* bit 15:12 */
|
||||
|
||||
/* Sonics side: PCI core and host control registers */
|
||||
struct sbpciregs {
|
||||
u32 control; /* PCI control */
|
||||
u32 PAD[3];
|
||||
u32 arbcontrol; /* PCI arbiter control */
|
||||
u32 clkrun; /* Clkrun Control (>=rev11) */
|
||||
u32 PAD[2];
|
||||
u32 intstatus; /* Interrupt status */
|
||||
u32 intmask; /* Interrupt mask */
|
||||
u32 sbtopcimailbox; /* Sonics to PCI mailbox */
|
||||
u32 PAD[9];
|
||||
u32 bcastaddr; /* Sonics broadcast address */
|
||||
u32 bcastdata; /* Sonics broadcast data */
|
||||
u32 PAD[2];
|
||||
u32 gpioin; /* ro: gpio input (>=rev2) */
|
||||
u32 gpioout; /* rw: gpio output (>=rev2) */
|
||||
u32 gpioouten; /* rw: gpio output enable (>= rev2) */
|
||||
u32 gpiocontrol; /* rw: gpio control (>= rev2) */
|
||||
u32 PAD[36];
|
||||
u32 sbtopci0; /* Sonics to PCI translation 0 */
|
||||
u32 sbtopci1; /* Sonics to PCI translation 1 */
|
||||
u32 sbtopci2; /* Sonics to PCI translation 2 */
|
||||
u32 PAD[189];
|
||||
u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
|
||||
u16 sprom[36]; /* SPROM shadow Area */
|
||||
u32 PAD[46];
|
||||
};
|
||||
|
||||
/* SB side: PCIE core and host control registers */
|
||||
struct sbpcieregs {
|
||||
u32 control; /* host mode only */
|
||||
u32 PAD[2];
|
||||
u32 biststatus; /* bist Status: 0x00C */
|
||||
u32 gpiosel; /* PCIE gpio sel: 0x010 */
|
||||
u32 gpioouten; /* PCIE gpio outen: 0x14 */
|
||||
u32 PAD[2];
|
||||
u32 intstatus; /* Interrupt status: 0x20 */
|
||||
u32 intmask; /* Interrupt mask: 0x24 */
|
||||
u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
|
||||
u32 PAD[53];
|
||||
u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
|
||||
u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
|
||||
u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
|
||||
u32 PAD[5];
|
||||
|
||||
/* pcie core supports in direct access to config space */
|
||||
u32 configaddr; /* pcie config space access: Address field: 0x120 */
|
||||
u32 configdata; /* pcie config space access: Data field: 0x124 */
|
||||
|
||||
/* mdio access to serdes */
|
||||
u32 mdiocontrol; /* controls the mdio access: 0x128 */
|
||||
u32 mdiodata; /* Data to the mdio access: 0x12c */
|
||||
|
||||
/* pcie protocol phy/dllp/tlp register indirect access mechanism */
|
||||
u32 pcieindaddr; /* indirect access to
|
||||
* the internal register: 0x130
|
||||
*/
|
||||
u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */
|
||||
|
||||
u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */
|
||||
u32 PAD[177];
|
||||
u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */
|
||||
u16 sprom[64]; /* SPROM shadow Area */
|
||||
};
|
||||
|
||||
struct pcicore_info {
|
||||
union {
|
||||
struct sbpcieregs __iomem *pcieregs;
|
||||
struct sbpciregs __iomem *pciregs;
|
||||
} regs; /* Memory mapped register to the core */
|
||||
|
||||
struct si_pub *sih; /* System interconnect handle */
|
||||
struct pci_dev *dev;
|
||||
u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
|
||||
* in the config space
|
||||
*/
|
||||
bool pcie_pr42767;
|
||||
u8 pcie_polarity;
|
||||
u8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */
|
||||
|
||||
u8 pmecap_offset; /* PM Capability offset in the config space */
|
||||
bool pmecap; /* Capable of generating PME */
|
||||
};
|
||||
|
||||
#define PCIE_ASPM(sih) \
|
||||
(((sih)->buscoretype == PCIE_CORE_ID) && \
|
||||
(((sih)->buscorerev >= 3) && \
|
||||
((sih)->buscorerev <= 5)))
|
||||
|
||||
|
||||
/* delay needed between the mdio control/ mdiodata register data access */
|
||||
static void pr28829_delay(void)
|
||||
{
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/* Initialize the PCI core.
|
||||
* It's caller's responsibility to make sure that this is done only once
|
||||
*/
|
||||
struct pcicore_info *pcicore_init(struct si_pub *sih, struct pci_dev *pdev,
|
||||
void __iomem *regs)
|
||||
{
|
||||
struct pcicore_info *pi;
|
||||
|
||||
/* alloc struct pcicore_info */
|
||||
pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
|
||||
if (pi == NULL)
|
||||
return NULL;
|
||||
|
||||
pi->sih = sih;
|
||||
pi->dev = pdev;
|
||||
|
||||
if (sih->buscoretype == PCIE_CORE_ID) {
|
||||
u8 cap_ptr;
|
||||
pi->regs.pcieregs = regs;
|
||||
cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
|
||||
NULL, NULL);
|
||||
pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
|
||||
} else
|
||||
pi->regs.pciregs = regs;
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
void pcicore_deinit(struct pcicore_info *pch)
|
||||
{
|
||||
kfree(pch);
|
||||
}
|
||||
|
||||
/* return cap_offset if requested capability exists in the PCI config space */
|
||||
/* Note that it's caller's responsibility to make sure it's a pci bus */
|
||||
u8
|
||||
pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
|
||||
unsigned char *buf, u32 *buflen)
|
||||
{
|
||||
u8 cap_id;
|
||||
u8 cap_ptr = 0;
|
||||
u32 bufsize;
|
||||
u8 byte_val;
|
||||
|
||||
/* check for Header type 0 */
|
||||
pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
|
||||
if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
|
||||
goto end;
|
||||
|
||||
/* check if the capability pointer field exists */
|
||||
pci_read_config_byte(dev, PCI_STATUS, &byte_val);
|
||||
if (!(byte_val & PCI_STATUS_CAP_LIST))
|
||||
goto end;
|
||||
|
||||
pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
|
||||
/* check if the capability pointer is 0x00 */
|
||||
if (cap_ptr == 0x00)
|
||||
goto end;
|
||||
|
||||
/* loop thru the capability list
|
||||
* and see if the pcie capability exists
|
||||
*/
|
||||
|
||||
pci_read_config_byte(dev, cap_ptr, &cap_id);
|
||||
|
||||
while (cap_id != req_cap_id) {
|
||||
pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
|
||||
if (cap_ptr == 0x00)
|
||||
break;
|
||||
pci_read_config_byte(dev, cap_ptr, &cap_id);
|
||||
}
|
||||
if (cap_id != req_cap_id)
|
||||
goto end;
|
||||
|
||||
/* found the caller requested capability */
|
||||
if (buf != NULL && buflen != NULL) {
|
||||
u8 cap_data;
|
||||
|
||||
bufsize = *buflen;
|
||||
if (!bufsize)
|
||||
goto end;
|
||||
*buflen = 0;
|
||||
/* copy the capability data excluding cap ID and next ptr */
|
||||
cap_data = cap_ptr + 2;
|
||||
if ((bufsize + cap_data) > PCI_SZPCR)
|
||||
bufsize = PCI_SZPCR - cap_data;
|
||||
*buflen = bufsize;
|
||||
while (bufsize--) {
|
||||
pci_read_config_byte(dev, cap_data, buf);
|
||||
cap_data++;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
end:
|
||||
return cap_ptr;
|
||||
}
|
||||
|
||||
/* ***** Register Access API */
|
||||
static uint
|
||||
pcie_readreg(struct sbpcieregs __iomem *pcieregs, uint addrtype, uint offset)
|
||||
{
|
||||
uint retval = 0xFFFFFFFF;
|
||||
|
||||
switch (addrtype) {
|
||||
case PCIE_CONFIGREGS:
|
||||
W_REG(&pcieregs->configaddr, offset);
|
||||
(void)R_REG((&pcieregs->configaddr));
|
||||
retval = R_REG(&pcieregs->configdata);
|
||||
break;
|
||||
case PCIE_PCIEREGS:
|
||||
W_REG(&pcieregs->pcieindaddr, offset);
|
||||
(void)R_REG(&pcieregs->pcieindaddr);
|
||||
retval = R_REG(&pcieregs->pcieinddata);
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static uint pcie_writereg(struct sbpcieregs __iomem *pcieregs, uint addrtype,
|
||||
uint offset, uint val)
|
||||
{
|
||||
switch (addrtype) {
|
||||
case PCIE_CONFIGREGS:
|
||||
W_REG((&pcieregs->configaddr), offset);
|
||||
W_REG((&pcieregs->configdata), val);
|
||||
break;
|
||||
case PCIE_PCIEREGS:
|
||||
W_REG((&pcieregs->pcieindaddr), offset);
|
||||
W_REG((&pcieregs->pcieinddata), val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
uint mdiodata, i = 0;
|
||||
uint pcie_serdes_spinwait = 200;
|
||||
|
||||
mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
|
||||
(MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
|
||||
(MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
|
||||
(blk << 4));
|
||||
W_REG(&pcieregs->mdiodata, mdiodata);
|
||||
|
||||
pr28829_delay();
|
||||
/* retry till the transaction is complete */
|
||||
while (i < pcie_serdes_spinwait) {
|
||||
if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE)
|
||||
break;
|
||||
|
||||
udelay(1000);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i >= pcie_serdes_spinwait)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
|
||||
uint *val)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
uint mdiodata;
|
||||
uint i = 0;
|
||||
uint pcie_serdes_spinwait = 10;
|
||||
|
||||
/* enable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
|
||||
|
||||
if (pi->sih->buscorerev >= 10) {
|
||||
/* new serdes is slower in rw,
|
||||
* using two layers of reg address mapping
|
||||
*/
|
||||
if (!pcie_mdiosetblock(pi, physmedia))
|
||||
return 1;
|
||||
mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
|
||||
(regaddr << MDIODATA_REGADDR_SHF));
|
||||
pcie_serdes_spinwait *= 20;
|
||||
} else {
|
||||
mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
|
||||
(regaddr << MDIODATA_REGADDR_SHF_OLD));
|
||||
}
|
||||
|
||||
if (!write)
|
||||
mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
|
||||
else
|
||||
mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
|
||||
*val);
|
||||
|
||||
W_REG(&pcieregs->mdiodata, mdiodata);
|
||||
|
||||
pr28829_delay();
|
||||
|
||||
/* retry till the transaction is complete */
|
||||
while (i < pcie_serdes_spinwait) {
|
||||
if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) {
|
||||
if (!write) {
|
||||
pr28829_delay();
|
||||
*val = (R_REG(&pcieregs->mdiodata) &
|
||||
MDIODATA_MASK);
|
||||
}
|
||||
/* Disable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, 0);
|
||||
return 0;
|
||||
}
|
||||
udelay(1000);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Timed out. Disable mdio access to SERDES. */
|
||||
W_REG(&pcieregs->mdiocontrol, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* use the mdio interface to read from mdio slaves */
|
||||
static int
|
||||
pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
|
||||
uint *regval)
|
||||
{
|
||||
return pcie_mdioop(pi, physmedia, regaddr, false, regval);
|
||||
}
|
||||
|
||||
/* use the mdio interface to write to mdio slaves */
|
||||
static int
|
||||
pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
|
||||
{
|
||||
return pcie_mdioop(pi, physmedia, regaddr, true, &val);
|
||||
}
|
||||
|
||||
/* ***** Support functions ***** */
|
||||
static u8 pcie_clkreq(struct pcicore_info *pi, u32 mask, u32 val)
|
||||
{
|
||||
u32 reg_val;
|
||||
u8 offset;
|
||||
|
||||
offset = pi->pciecap_lcreg_offset;
|
||||
if (!offset)
|
||||
return 0;
|
||||
|
||||
pci_read_config_dword(pi->dev, offset, ®_val);
|
||||
/* set operation */
|
||||
if (mask) {
|
||||
if (val)
|
||||
reg_val |= PCIE_CLKREQ_ENAB;
|
||||
else
|
||||
reg_val &= ~PCIE_CLKREQ_ENAB;
|
||||
pci_write_config_dword(pi->dev, offset, reg_val);
|
||||
pci_read_config_dword(pi->dev, offset, ®_val);
|
||||
}
|
||||
if (reg_val & PCIE_CLKREQ_ENAB)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
|
||||
{
|
||||
u32 w;
|
||||
struct si_pub *sih = pi->sih;
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
|
||||
if (sih->buscoretype != PCIE_CORE_ID || sih->buscorerev < 7)
|
||||
return;
|
||||
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
if (extend)
|
||||
w |= PCIE_ASPMTIMER_EXTEND;
|
||||
else
|
||||
w &= ~PCIE_ASPMTIMER_EXTEND;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
}
|
||||
|
||||
/* centralized clkreq control policy */
|
||||
static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
|
||||
switch (state) {
|
||||
case SI_DOATTACH:
|
||||
if (PCIE_ASPM(sih))
|
||||
pcie_clkreq(pi, 1, 0);
|
||||
break;
|
||||
case SI_PCIDOWN:
|
||||
if (sih->buscorerev == 6) { /* turn on serdes PLL down */
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data),
|
||||
~0x40, 0);
|
||||
} else if (pi->pcie_pr42767) {
|
||||
pcie_clkreq(pi, 1, 1);
|
||||
}
|
||||
break;
|
||||
case SI_PCIUP:
|
||||
if (sih->buscorerev == 6) { /* turn off serdes PLL down */
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data),
|
||||
~0x40, 0x40);
|
||||
} else if (PCIE_ASPM(sih)) { /* disable clkreq */
|
||||
pcie_clkreq(pi, 1, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ***** PCI core WARs ***** */
|
||||
/* Done only once at attach time */
|
||||
static void pcie_war_polarity(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w;
|
||||
|
||||
if (pi->pcie_polarity != 0)
|
||||
return;
|
||||
|
||||
w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
|
||||
|
||||
/* Detect the current polarity at attach and force that polarity and
|
||||
* disable changing the polarity
|
||||
*/
|
||||
if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
|
||||
pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
|
||||
else
|
||||
pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
|
||||
SERDES_RX_CTRL_POLARITY);
|
||||
}
|
||||
|
||||
/* enable ASPM and CLKREQ if srom doesn't have it */
|
||||
/* Needs to happen when update to shadow SROM is needed
|
||||
* : Coming out of 'standby'/'hibernate'
|
||||
* : If pcie_war_aspm_ovr state changed
|
||||
*/
|
||||
static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
struct si_pub *sih = pi->sih;
|
||||
u16 val16;
|
||||
u16 __iomem *reg16;
|
||||
u32 w;
|
||||
|
||||
if (!PCIE_ASPM(sih))
|
||||
return;
|
||||
|
||||
/* bypass this on QT or VSIM */
|
||||
reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
val16 &= ~SRSH_ASPM_ENB;
|
||||
if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
|
||||
val16 |= SRSH_ASPM_ENB;
|
||||
else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
|
||||
val16 |= SRSH_ASPM_L1_ENB;
|
||||
else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
|
||||
val16 |= SRSH_ASPM_L0s_ENB;
|
||||
|
||||
W_REG(reg16, val16);
|
||||
|
||||
pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
|
||||
w &= ~PCIE_ASPM_ENAB;
|
||||
w |= pi->pcie_war_aspm_ovr;
|
||||
pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
|
||||
|
||||
reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
|
||||
val16 |= SRSH_CLKREQ_ENB;
|
||||
pi->pcie_pr42767 = true;
|
||||
} else
|
||||
val16 &= ~SRSH_CLKREQ_ENB;
|
||||
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
|
||||
/* Apply the polarity determined at the start */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_serdes(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w = 0;
|
||||
|
||||
if (pi->pcie_polarity != 0)
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
|
||||
pi->pcie_polarity);
|
||||
|
||||
pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
|
||||
if (w & PLL_CTRL_FREQDET_EN) {
|
||||
w &= ~PLL_CTRL_FREQDET_EN;
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_misc_config_fixup(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u16 val16;
|
||||
u16 __iomem *reg16;
|
||||
|
||||
reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
|
||||
val16 |= SRSH_L23READY_EXIT_NOPERST;
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
}
|
||||
|
||||
/* quick hack for testing */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_noplldown(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u16 __iomem *reg16;
|
||||
|
||||
/* turn off serdes PLL down */
|
||||
ai_corereg(pi->sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol),
|
||||
CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
|
||||
|
||||
/* clear srom shadow backdoor */
|
||||
reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
|
||||
W_REG(reg16, 0);
|
||||
}
|
||||
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_pci_setup(struct pcicore_info *pi)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u32 w;
|
||||
|
||||
if (sih->buscorerev == 0 || sih->buscorerev == 1) {
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_TLP_WORKAROUNDSREG);
|
||||
w |= 0x8;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_TLP_WORKAROUNDSREG, w);
|
||||
}
|
||||
|
||||
if (sih->buscorerev == 1) {
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
|
||||
w |= 0x40;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
|
||||
}
|
||||
|
||||
if (sih->buscorerev == 0) {
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
|
||||
} else if (PCIE_ASPM(sih)) {
|
||||
/* Change the L1 threshold for better performance */
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_DLLP_PMTHRESHREG);
|
||||
w &= ~PCIE_L1THRESHOLDTIME_MASK;
|
||||
w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_DLLP_PMTHRESHREG, w);
|
||||
|
||||
pcie_war_serdes(pi);
|
||||
|
||||
pcie_war_aspm_clkreq(pi);
|
||||
} else if (pi->sih->buscorerev == 7)
|
||||
pcie_war_noplldown(pi);
|
||||
|
||||
/* Note that the fix is actually in the SROM,
|
||||
* that's why this is open-ended
|
||||
*/
|
||||
if (pi->sih->buscorerev >= 6)
|
||||
pcie_misc_config_fixup(pi);
|
||||
}
|
||||
|
||||
/* ***** Functions called during driver state changes ***** */
|
||||
void pcicore_attach(struct pcicore_info *pi, int state)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
u32 bfl2 = (u32)getintvar(sih, BRCMS_SROM_BOARDFLAGS2);
|
||||
|
||||
/* Determine if this board needs override */
|
||||
if (PCIE_ASPM(sih)) {
|
||||
if (bfl2 & BFL2_PCIEWAR_OVR)
|
||||
pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
|
||||
else
|
||||
pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
|
||||
}
|
||||
|
||||
/* These need to happen in this order only */
|
||||
pcie_war_polarity(pi);
|
||||
|
||||
pcie_war_serdes(pi);
|
||||
|
||||
pcie_war_aspm_clkreq(pi);
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
|
||||
}
|
||||
|
||||
void pcicore_hwup(struct pcicore_info *pi)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
pcie_war_pci_setup(pi);
|
||||
}
|
||||
|
||||
void pcicore_up(struct pcicore_info *pi, int state)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
/* Restore L1 timer for better performance */
|
||||
pcie_extendL1timer(pi, true);
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
}
|
||||
|
||||
/* When the device is going to enter D3 state
|
||||
* (or the system is going to enter S3/S4 states)
|
||||
*/
|
||||
void pcicore_sleep(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w;
|
||||
|
||||
if (!pi || !PCIE_ASPM(pi->sih))
|
||||
return;
|
||||
|
||||
pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
|
||||
w &= ~PCIE_CAP_LCREG_ASPML1;
|
||||
pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
|
||||
|
||||
pi->pcie_pr42767 = false;
|
||||
}
|
||||
|
||||
void pcicore_down(struct pcicore_info *pi, int state)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
|
||||
/* Reduce L1 timer for better power savings */
|
||||
pcie_extendL1timer(pi, false);
|
||||
}
|
||||
|
||||
/* precondition: current core is sii->buscoretype */
|
||||
static void pcicore_fixcfg(struct pcicore_info *pi, u16 __iomem *reg16)
|
||||
{
|
||||
struct si_info *sii = (struct si_info *)(pi->sih);
|
||||
u16 val16;
|
||||
uint pciidx;
|
||||
|
||||
pciidx = ai_coreidx(&sii->pub);
|
||||
val16 = R_REG(reg16);
|
||||
if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) {
|
||||
val16 = (u16)(pciidx << SRSH_PI_SHIFT) |
|
||||
(val16 & ~SRSH_PI_MASK);
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pcicore_fixcfg_pci(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
|
||||
{
|
||||
pcicore_fixcfg(pi, &pciregs->sprom[SRSH_PI_OFFSET]);
|
||||
}
|
||||
|
||||
void pcicore_fixcfg_pcie(struct pcicore_info *pi,
|
||||
struct sbpcieregs __iomem *pcieregs)
|
||||
{
|
||||
pcicore_fixcfg(pi, &pcieregs->sprom[SRSH_PI_OFFSET]);
|
||||
}
|
||||
|
||||
/* precondition: current core is pci core */
|
||||
void
|
||||
pcicore_pci_setup(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
|
||||
{
|
||||
u32 w;
|
||||
|
||||
OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST);
|
||||
|
||||
if (((struct si_info *)(pi->sih))->pub.buscorerev >= 11) {
|
||||
OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
|
||||
w = R_REG(&pciregs->clkrun);
|
||||
W_REG(&pciregs->clkrun, w | PCI_CLKRUN_DSBL);
|
||||
w = R_REG(&pciregs->clkrun);
|
||||
}
|
||||
}
|
82
drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
Normal file
82
drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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_NICPCI_H_
|
||||
#define _BRCM_NICPCI_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* PCI configuration address space size */
|
||||
#define PCI_SZPCR 256
|
||||
|
||||
/* Brcm PCI configuration registers */
|
||||
/* backplane address space accessed by BAR0 */
|
||||
#define PCI_BAR0_WIN 0x80
|
||||
/* sprom property control */
|
||||
#define PCI_SPROM_CONTROL 0x88
|
||||
/* mask of PCI and other cores interrupts */
|
||||
#define PCI_INT_MASK 0x94
|
||||
/* backplane core interrupt mask bits offset */
|
||||
#define PCI_SBIM_SHIFT 8
|
||||
/* backplane address space accessed by second 4KB of BAR0 */
|
||||
#define PCI_BAR0_WIN2 0xac
|
||||
/* pci config space gpio input (>=rev3) */
|
||||
#define PCI_GPIO_IN 0xb0
|
||||
/* pci config space gpio output (>=rev3) */
|
||||
#define PCI_GPIO_OUT 0xb4
|
||||
/* pci config space gpio output enable (>=rev3) */
|
||||
#define PCI_GPIO_OUTEN 0xb8
|
||||
|
||||
/* bar0 + 4K accesses external sprom */
|
||||
#define PCI_BAR0_SPROM_OFFSET (4 * 1024)
|
||||
/* bar0 + 6K accesses pci core registers */
|
||||
#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024)
|
||||
/*
|
||||
* pci core SB registers are at the end of the
|
||||
* 8KB window, so their address is the "regular"
|
||||
* address plus 4K
|
||||
*/
|
||||
#define PCI_BAR0_PCISBR_OFFSET (4 * 1024)
|
||||
/* bar0 window size Match with corerev 13 */
|
||||
#define PCI_BAR0_WINSZ (16 * 1024)
|
||||
/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
|
||||
/* bar0 + 8K accesses pci/pcie core registers */
|
||||
#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)
|
||||
/* bar0 + 12K accesses chipc core registers */
|
||||
#define PCI_16KB0_CCREGS_OFFSET (12 * 1024)
|
||||
|
||||
struct sbpciregs;
|
||||
struct sbpcieregs;
|
||||
|
||||
extern struct pcicore_info *pcicore_init(struct si_pub *sih,
|
||||
struct pci_dev *pdev,
|
||||
void __iomem *regs);
|
||||
extern void pcicore_deinit(struct pcicore_info *pch);
|
||||
extern void pcicore_attach(struct pcicore_info *pch, int state);
|
||||
extern void pcicore_hwup(struct pcicore_info *pch);
|
||||
extern void pcicore_up(struct pcicore_info *pch, int state);
|
||||
extern void pcicore_sleep(struct pcicore_info *pch);
|
||||
extern void pcicore_down(struct pcicore_info *pch, int state);
|
||||
extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
|
||||
unsigned char *buf, u32 *buflen);
|
||||
extern void pcicore_fixcfg_pci(struct pcicore_info *pch,
|
||||
struct sbpciregs __iomem *pciregs);
|
||||
extern void pcicore_fixcfg_pcie(struct pcicore_info *pch,
|
||||
struct sbpcieregs __iomem *pciregs);
|
||||
extern void pcicore_pci_setup(struct pcicore_info *pch,
|
||||
struct sbpciregs __iomem *pciregs);
|
||||
|
||||
#endif /* _BRCM_NICPCI_H_ */
|
426
drivers/net/wireless/brcm80211/brcmsmac/otp.c
Normal file
426
drivers/net/wireless/brcm80211/brcmsmac/otp.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* 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/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <chipcommon.h>
|
||||
#include "aiutils.h"
|
||||
#include "otp.h"
|
||||
|
||||
#define OTPS_GUP_MASK 0x00000f00
|
||||
#define OTPS_GUP_SHIFT 8
|
||||
/* h/w subregion is programmed */
|
||||
#define OTPS_GUP_HW 0x00000100
|
||||
/* s/w subregion is programmed */
|
||||
#define OTPS_GUP_SW 0x00000200
|
||||
/* chipid/pkgopt subregion is programmed */
|
||||
#define OTPS_GUP_CI 0x00000400
|
||||
/* fuse subregion is programmed */
|
||||
#define OTPS_GUP_FUSE 0x00000800
|
||||
|
||||
/* Fields in otpprog in rev >= 21 */
|
||||
#define OTPP_COL_MASK 0x000000ff
|
||||
#define OTPP_COL_SHIFT 0
|
||||
#define OTPP_ROW_MASK 0x0000ff00
|
||||
#define OTPP_ROW_SHIFT 8
|
||||
#define OTPP_OC_MASK 0x0f000000
|
||||
#define OTPP_OC_SHIFT 24
|
||||
#define OTPP_READERR 0x10000000
|
||||
#define OTPP_VALUE_MASK 0x20000000
|
||||
#define OTPP_VALUE_SHIFT 29
|
||||
#define OTPP_START_BUSY 0x80000000
|
||||
#define OTPP_READ 0x40000000
|
||||
|
||||
/* Opcodes for OTPP_OC field */
|
||||
#define OTPPOC_READ 0
|
||||
#define OTPPOC_BIT_PROG 1
|
||||
#define OTPPOC_VERIFY 3
|
||||
#define OTPPOC_INIT 4
|
||||
#define OTPPOC_SET 5
|
||||
#define OTPPOC_RESET 6
|
||||
#define OTPPOC_OCST 7
|
||||
#define OTPPOC_ROW_LOCK 8
|
||||
#define OTPPOC_PRESCN_TEST 9
|
||||
|
||||
#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
|
||||
|
||||
#define OTPP_TRIES 10000000 /* # of tries for OTPP */
|
||||
|
||||
#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
|
||||
|
||||
/* Fixed size subregions sizes in words */
|
||||
#define OTPGU_CI_SZ 2
|
||||
|
||||
struct otpinfo;
|
||||
|
||||
/* OTP function struct */
|
||||
struct otp_fn_s {
|
||||
int (*init)(struct si_pub *sih, struct otpinfo *oi);
|
||||
int (*read_region)(struct otpinfo *oi, int region, u16 *data,
|
||||
uint *wlen);
|
||||
};
|
||||
|
||||
struct otpinfo {
|
||||
uint ccrev; /* chipc revision */
|
||||
const struct otp_fn_s *fn; /* OTP functions */
|
||||
struct si_pub *sih; /* Saved sb handle */
|
||||
|
||||
/* IPX OTP section */
|
||||
u16 wsize; /* Size of otp in words */
|
||||
u16 rows; /* Geometry */
|
||||
u16 cols; /* Geometry */
|
||||
u32 status; /* Flag bits (lock/prog/rv).
|
||||
* (Reflected only when OTP is power cycled)
|
||||
*/
|
||||
u16 hwbase; /* hardware subregion offset */
|
||||
u16 hwlim; /* hardware subregion boundary */
|
||||
u16 swbase; /* software subregion offset */
|
||||
u16 swlim; /* software subregion boundary */
|
||||
u16 fbase; /* fuse subregion offset */
|
||||
u16 flim; /* fuse subregion boundary */
|
||||
int otpgu_base; /* offset to General Use Region */
|
||||
};
|
||||
|
||||
/* OTP layout */
|
||||
/* CC revs 21, 24 and 27 OTP General Use Region word offset */
|
||||
#define REVA4_OTPGU_BASE 12
|
||||
|
||||
/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
|
||||
#define REVB8_OTPGU_BASE 20
|
||||
|
||||
/* CC rev 36 OTP General Use Region word offset */
|
||||
#define REV36_OTPGU_BASE 12
|
||||
|
||||
/* Subregion word offsets in General Use region */
|
||||
#define OTPGU_HSB_OFF 0
|
||||
#define OTPGU_SFB_OFF 1
|
||||
#define OTPGU_CI_OFF 2
|
||||
#define OTPGU_P_OFF 3
|
||||
#define OTPGU_SROM_OFF 4
|
||||
|
||||
/* Flag bit offsets in General Use region */
|
||||
#define OTPGU_HWP_OFF 60
|
||||
#define OTPGU_SWP_OFF 61
|
||||
#define OTPGU_CIP_OFF 62
|
||||
#define OTPGU_FUSEP_OFF 63
|
||||
#define OTPGU_CIP_MSK 0x4000
|
||||
#define OTPGU_P_MSK 0xf000
|
||||
#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
|
||||
|
||||
/* OTP Size */
|
||||
#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */
|
||||
#define OTP_SZ_FU_288 (288/8) /* 288 bits */
|
||||
#define OTP_SZ_FU_216 (216/8) /* 216 bits */
|
||||
#define OTP_SZ_FU_72 (72/8) /* 72 bits */
|
||||
#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
|
||||
#define OTP4315_SWREG_SZ 178 /* 178 bytes */
|
||||
#define OTP_SZ_FU_144 (144/8) /* 144 bits */
|
||||
|
||||
static u16
|
||||
ipxotp_otpr(struct otpinfo *oi, struct chipcregs __iomem *cc, uint wn)
|
||||
{
|
||||
return R_REG(&cc->sromotp[wn]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate max HW/SW region byte size by subtracting fuse region
|
||||
* and checksum size, osizew is oi->wsize (OTP size - GU size) in words
|
||||
*/
|
||||
static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
|
||||
break;
|
||||
case BCM4313_CHIP_ID:
|
||||
ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
|
||||
break;
|
||||
default:
|
||||
break; /* Don't know about this chip */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
|
||||
{
|
||||
uint k;
|
||||
u32 otpp, st;
|
||||
|
||||
/*
|
||||
* record word offset of General Use Region
|
||||
* for various chipcommon revs
|
||||
*/
|
||||
if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
|
||||
|| oi->sih->ccrev == 27) {
|
||||
oi->otpgu_base = REVA4_OTPGU_BASE;
|
||||
} else if (oi->sih->ccrev == 36) {
|
||||
/*
|
||||
* OTP size greater than equal to 2KB (128 words),
|
||||
* otpgu_base is similar to rev23
|
||||
*/
|
||||
if (oi->wsize >= 128)
|
||||
oi->otpgu_base = REVB8_OTPGU_BASE;
|
||||
else
|
||||
oi->otpgu_base = REV36_OTPGU_BASE;
|
||||
} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
|
||||
oi->otpgu_base = REVB8_OTPGU_BASE;
|
||||
}
|
||||
|
||||
/* First issue an init command so the status is up to date */
|
||||
otpp =
|
||||
OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
|
||||
|
||||
W_REG(&cc->otpprog, otpp);
|
||||
for (k = 0;
|
||||
((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
|
||||
&& (k < OTPP_TRIES); k++)
|
||||
;
|
||||
if (k >= OTPP_TRIES)
|
||||
return;
|
||||
|
||||
/* Read OTP lock bits and subregion programmed indication bits */
|
||||
oi->status = R_REG(&cc->otpstatus);
|
||||
|
||||
if ((oi->sih->chip == BCM43224_CHIP_ID)
|
||||
|| (oi->sih->chip == BCM43225_CHIP_ID)) {
|
||||
u32 p_bits;
|
||||
p_bits =
|
||||
(ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
|
||||
OTPGU_P_MSK)
|
||||
>> OTPGU_P_SHIFT;
|
||||
oi->status |= (p_bits << OTPS_GUP_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* h/w region base and fuse region limit are fixed to
|
||||
* the top and the bottom of the general use region.
|
||||
* Everything else can be flexible.
|
||||
*/
|
||||
oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
|
||||
oi->hwlim = oi->wsize;
|
||||
if (oi->status & OTPS_GUP_HW) {
|
||||
oi->hwlim =
|
||||
ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
|
||||
oi->swbase = oi->hwlim;
|
||||
} else
|
||||
oi->swbase = oi->hwbase;
|
||||
|
||||
/* subtract fuse and checksum from beginning */
|
||||
oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
|
||||
|
||||
if (oi->status & OTPS_GUP_SW) {
|
||||
oi->swlim =
|
||||
ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
|
||||
oi->fbase = oi->swlim;
|
||||
} else
|
||||
oi->fbase = oi->swbase;
|
||||
|
||||
oi->flim = oi->wsize;
|
||||
}
|
||||
|
||||
static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
{
|
||||
uint idx;
|
||||
struct chipcregs __iomem *cc;
|
||||
|
||||
/* Make sure we're running IPX OTP */
|
||||
if (!OTPTYPE_IPX(sih->ccrev))
|
||||
return -EBADE;
|
||||
|
||||
/* Make sure OTP is not disabled */
|
||||
if (ai_is_otp_disabled(sih))
|
||||
return -EBADE;
|
||||
|
||||
/* Check for otp size */
|
||||
switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
|
||||
case 0:
|
||||
/* Nothing there */
|
||||
return -EBADE;
|
||||
case 1: /* 32x64 */
|
||||
oi->rows = 32;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 128;
|
||||
break;
|
||||
case 2: /* 64x64 */
|
||||
oi->rows = 64;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 256;
|
||||
break;
|
||||
case 5: /* 96x64 */
|
||||
oi->rows = 96;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 384;
|
||||
break;
|
||||
case 7: /* 16x64 *//* 1024 bits */
|
||||
oi->rows = 16;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 64;
|
||||
break;
|
||||
default:
|
||||
/* Don't know the geometry */
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
/* Retrieve OTP region info */
|
||||
idx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
_ipxotp_init(oi, cc);
|
||||
|
||||
ai_setcoreidx(sih, idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen)
|
||||
{
|
||||
uint idx;
|
||||
struct chipcregs __iomem *cc;
|
||||
uint base, i, sz;
|
||||
|
||||
/* Validate region selection */
|
||||
switch (region) {
|
||||
case OTP_HW_RGN:
|
||||
sz = (uint) oi->hwlim - oi->hwbase;
|
||||
if (!(oi->status & OTPS_GUP_HW)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->hwbase;
|
||||
break;
|
||||
case OTP_SW_RGN:
|
||||
sz = ((uint) oi->swlim - oi->swbase);
|
||||
if (!(oi->status & OTPS_GUP_SW)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->swbase;
|
||||
break;
|
||||
case OTP_CI_RGN:
|
||||
sz = OTPGU_CI_SZ;
|
||||
if (!(oi->status & OTPS_GUP_CI)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->otpgu_base + OTPGU_CI_OFF;
|
||||
break;
|
||||
case OTP_FUSE_RGN:
|
||||
sz = (uint) oi->flim - oi->fbase;
|
||||
if (!(oi->status & OTPS_GUP_FUSE)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->fbase;
|
||||
break;
|
||||
case OTP_ALL_RGN:
|
||||
sz = ((uint) oi->flim - oi->hwbase);
|
||||
if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->hwbase;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
idx = ai_coreidx(oi->sih);
|
||||
cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
|
||||
|
||||
/* Read the data */
|
||||
for (i = 0; i < sz; i++)
|
||||
data[i] = ipxotp_otpr(oi, cc, base + i);
|
||||
|
||||
ai_setcoreidx(oi->sih, idx);
|
||||
*wlen = sz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct otp_fn_s ipxotp_fn = {
|
||||
(int (*)(struct si_pub *, struct otpinfo *)) ipxotp_init,
|
||||
(int (*)(struct otpinfo *, int, u16 *, uint *)) ipxotp_read_region,
|
||||
};
|
||||
|
||||
static int otp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
{
|
||||
|
||||
int ret;
|
||||
|
||||
memset(oi, 0, sizeof(struct otpinfo));
|
||||
|
||||
oi->ccrev = sih->ccrev;
|
||||
|
||||
if (OTPTYPE_IPX(oi->ccrev))
|
||||
oi->fn = &ipxotp_fn;
|
||||
|
||||
if (oi->fn == NULL)
|
||||
return -EBADE;
|
||||
|
||||
oi->sih = sih;
|
||||
|
||||
ret = (oi->fn->init) (sih, oi);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) {
|
||||
struct otpinfo otpinfo;
|
||||
struct otpinfo *oi = &otpinfo;
|
||||
int err = 0;
|
||||
|
||||
if (ai_is_otp_disabled(sih)) {
|
||||
err = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = otp_init(sih, oi);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = ((oi)->fn->read_region)(oi, region, data, wlen);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
36
drivers/net/wireless/brcm80211/brcmsmac/otp.h
Normal file
36
drivers/net/wireless/brcm80211/brcmsmac/otp.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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_OTP_H_
|
||||
#define _BRCM_OTP_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* OTP regions */
|
||||
#define OTP_HW_RGN 1
|
||||
#define OTP_SW_RGN 2
|
||||
#define OTP_CI_RGN 4
|
||||
#define OTP_FUSE_RGN 8
|
||||
/* From h/w region to end of OTP including checksum */
|
||||
#define OTP_ALL_RGN 0xf
|
||||
|
||||
/* OTP Size */
|
||||
#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */
|
||||
|
||||
extern int otp_read_region(struct si_pub *sih, int region, u16 *data,
|
||||
uint *wlen);
|
||||
|
||||
#endif /* _BRCM_OTP_H_ */
|
2988
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
Normal file
2988
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
Normal file
File diff suppressed because it is too large
Load Diff
301
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
Normal file
301
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* phy_hal.h: functionality exported from the phy to higher layers
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PHY_HAL_H_
|
||||
#define _BRCM_PHY_HAL_H_
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <phy_shim.h>
|
||||
|
||||
#define IDCODE_VER_MASK 0x0000000f
|
||||
#define IDCODE_VER_SHIFT 0
|
||||
#define IDCODE_MFG_MASK 0x00000fff
|
||||
#define IDCODE_MFG_SHIFT 0
|
||||
#define IDCODE_ID_MASK 0x0ffff000
|
||||
#define IDCODE_ID_SHIFT 12
|
||||
#define IDCODE_REV_MASK 0xf0000000
|
||||
#define IDCODE_REV_SHIFT 28
|
||||
|
||||
#define NORADIO_ID 0xe4f5
|
||||
#define NORADIO_IDCODE 0x4e4f5246
|
||||
|
||||
#define BCM2055_ID 0x2055
|
||||
#define BCM2055_IDCODE 0x02055000
|
||||
#define BCM2055A0_IDCODE 0x1205517f
|
||||
|
||||
#define BCM2056_ID 0x2056
|
||||
#define BCM2056_IDCODE 0x02056000
|
||||
#define BCM2056A0_IDCODE 0x1205617f
|
||||
|
||||
#define BCM2057_ID 0x2057
|
||||
#define BCM2057_IDCODE 0x02057000
|
||||
#define BCM2057A0_IDCODE 0x1205717f
|
||||
|
||||
#define BCM2064_ID 0x2064
|
||||
#define BCM2064_IDCODE 0x02064000
|
||||
#define BCM2064A0_IDCODE 0x0206417f
|
||||
|
||||
#define PHY_TPC_HW_OFF false
|
||||
#define PHY_TPC_HW_ON true
|
||||
|
||||
#define PHY_PERICAL_DRIVERUP 1
|
||||
#define PHY_PERICAL_WATCHDOG 2
|
||||
#define PHY_PERICAL_PHYINIT 3
|
||||
#define PHY_PERICAL_JOIN_BSS 4
|
||||
#define PHY_PERICAL_START_IBSS 5
|
||||
#define PHY_PERICAL_UP_BSS 6
|
||||
#define PHY_PERICAL_CHAN 7
|
||||
#define PHY_FULLCAL 8
|
||||
|
||||
#define PHY_PERICAL_DISABLE 0
|
||||
#define PHY_PERICAL_SPHASE 1
|
||||
#define PHY_PERICAL_MPHASE 2
|
||||
#define PHY_PERICAL_MANUAL 3
|
||||
|
||||
#define PHY_HOLD_FOR_ASSOC 1
|
||||
#define PHY_HOLD_FOR_SCAN 2
|
||||
#define PHY_HOLD_FOR_RM 4
|
||||
#define PHY_HOLD_FOR_PLT 8
|
||||
#define PHY_HOLD_FOR_MUTE 16
|
||||
#define PHY_HOLD_FOR_NOT_ASSOC 0x20
|
||||
|
||||
#define PHY_MUTE_FOR_PREISM 1
|
||||
#define PHY_MUTE_ALL 0xffffffff
|
||||
|
||||
#define PHY_NOISE_FIXED_VAL (-95)
|
||||
#define PHY_NOISE_FIXED_VAL_NPHY (-92)
|
||||
#define PHY_NOISE_FIXED_VAL_LCNPHY (-92)
|
||||
|
||||
#define PHY_MODE_CAL 0x0002
|
||||
#define PHY_MODE_NOISEM 0x0004
|
||||
|
||||
#define BRCMS_TXPWR_DB_FACTOR 4
|
||||
|
||||
/* a large TX Power as an init value to factor out of min() calculations,
|
||||
* keep low enough to fit in an s8, units are .25 dBm
|
||||
*/
|
||||
#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
|
||||
|
||||
#define BRCMS_NUM_RATES_CCK 4
|
||||
#define BRCMS_NUM_RATES_OFDM 8
|
||||
#define BRCMS_NUM_RATES_MCS_1_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_2_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_3_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_4_STREAM 8
|
||||
|
||||
#define BRCMS_RSSI_INVALID 0 /* invalid RSSI value */
|
||||
|
||||
struct d11regs;
|
||||
struct phy_shim_info;
|
||||
|
||||
struct txpwr_limits {
|
||||
u8 cck[BRCMS_NUM_RATES_CCK];
|
||||
u8 ofdm[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
|
||||
u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
|
||||
|
||||
u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
|
||||
u8 mcs32;
|
||||
};
|
||||
|
||||
struct tx_power {
|
||||
u32 flags;
|
||||
u16 chanspec; /* txpwr report for this channel */
|
||||
u16 local_chanspec; /* channel on which we are associated */
|
||||
u8 local_max; /* local max according to the AP */
|
||||
u8 local_constraint; /* local constraint according to the AP */
|
||||
s8 antgain[2]; /* Ant gain for each band - from SROM */
|
||||
u8 rf_cores; /* count of RF Cores being reported */
|
||||
u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
|
||||
u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain
|
||||
* without adjustment */
|
||||
u8 est_Pout_cck; /* Latest CCK tx power out estimate */
|
||||
u8 tx_power_max[4]; /* Maximum target power among all rates */
|
||||
/* Index of the rate with the max target power */
|
||||
u8 tx_power_max_rate_ind[4];
|
||||
/* User limit */
|
||||
u8 user_limit[WL_TX_POWER_RATES];
|
||||
/* Regulatory power limit */
|
||||
u8 reg_limit[WL_TX_POWER_RATES];
|
||||
/* Max power board can support (SROM) */
|
||||
u8 board_limit[WL_TX_POWER_RATES];
|
||||
/* Latest target power */
|
||||
u8 target[WL_TX_POWER_RATES];
|
||||
};
|
||||
|
||||
struct tx_inst_power {
|
||||
u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
|
||||
u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
|
||||
};
|
||||
|
||||
struct brcms_chanvec {
|
||||
u8 vec[MAXCHANNEL / NBBY];
|
||||
};
|
||||
|
||||
struct shared_phy_params {
|
||||
struct si_pub *sih;
|
||||
struct phy_shim_info *physhim;
|
||||
uint unit;
|
||||
uint corerev;
|
||||
uint buscorerev;
|
||||
u16 vid;
|
||||
u16 did;
|
||||
uint chip;
|
||||
uint chiprev;
|
||||
uint chippkg;
|
||||
uint sromrev;
|
||||
uint boardtype;
|
||||
uint boardrev;
|
||||
uint boardvendor;
|
||||
u32 boardflags;
|
||||
u32 boardflags2;
|
||||
};
|
||||
|
||||
|
||||
extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
|
||||
extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh,
|
||||
struct d11regs __iomem *regs,
|
||||
int bandtype, struct wiphy *wiphy);
|
||||
extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
|
||||
u16 *phyrev, u16 *radioid,
|
||||
u16 *radiover);
|
||||
extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
|
||||
extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
|
||||
|
||||
extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
|
||||
extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
|
||||
extern void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec);
|
||||
extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
|
||||
extern int wlc_phy_down(struct brcms_phy_pub *ppi);
|
||||
extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
|
||||
extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
|
||||
|
||||
extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi,
|
||||
u16 chanspec);
|
||||
extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
|
||||
u16 newch);
|
||||
extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
|
||||
|
||||
extern int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
|
||||
struct d11rxhdr *rxh);
|
||||
extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
|
||||
extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
|
||||
|
||||
extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
|
||||
extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
|
||||
|
||||
|
||||
extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
|
||||
|
||||
extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
|
||||
bool wide_filter);
|
||||
extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
|
||||
struct brcms_chanvec *channels);
|
||||
extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi,
|
||||
uint band);
|
||||
|
||||
extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan,
|
||||
u8 *_min_, u8 *_max_, int rate);
|
||||
extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi,
|
||||
uint chan, u8 *_max_, u8 *_min_);
|
||||
extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi,
|
||||
uint band, s32 *, s32 *, u32 *);
|
||||
extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi,
|
||||
struct txpwr_limits *,
|
||||
u16 chanspec);
|
||||
extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm,
|
||||
bool *override);
|
||||
extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm,
|
||||
bool override);
|
||||
extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
|
||||
struct txpwr_limits *);
|
||||
extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi,
|
||||
bool hwpwrctrl);
|
||||
extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
|
||||
extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
|
||||
extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
|
||||
|
||||
extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain,
|
||||
u8 rxchain);
|
||||
extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain,
|
||||
u8 rxchain);
|
||||
extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain,
|
||||
u8 *rxchain);
|
||||
extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
|
||||
extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih,
|
||||
u16 chanspec);
|
||||
extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
|
||||
|
||||
extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
|
||||
extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
|
||||
extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
|
||||
extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val);
|
||||
extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags);
|
||||
|
||||
extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
|
||||
|
||||
extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
|
||||
struct tx_power *power, uint channel);
|
||||
|
||||
extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
|
||||
extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi,
|
||||
u8 txpwr_percent);
|
||||
extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
|
||||
extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih,
|
||||
bool bf_preempt);
|
||||
extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
|
||||
|
||||
extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
|
||||
|
||||
extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
|
||||
|
||||
extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
|
||||
u8 mcs_offset);
|
||||
extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
|
||||
#endif /* _BRCM_PHY_HAL_H_ */
|
1169
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
Normal file
1169
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
Normal file
File diff suppressed because it is too large
Load Diff
5154
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
Normal file
5154
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
Normal file
File diff suppressed because it is too large
Load Diff
121
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
Normal file
121
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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_PHY_LCN_H_
|
||||
#define _BRCM_PHY_LCN_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
struct brcms_phy_lcnphy {
|
||||
int lcnphy_txrf_sp_9_override;
|
||||
u8 lcnphy_full_cal_channel;
|
||||
u8 lcnphy_cal_counter;
|
||||
u16 lcnphy_cal_temper;
|
||||
bool lcnphy_recal;
|
||||
|
||||
u8 lcnphy_rc_cap;
|
||||
u32 lcnphy_mcs20_po;
|
||||
|
||||
u8 lcnphy_tr_isolation_mid;
|
||||
u8 lcnphy_tr_isolation_low;
|
||||
u8 lcnphy_tr_isolation_hi;
|
||||
|
||||
u8 lcnphy_bx_arch;
|
||||
u8 lcnphy_rx_power_offset;
|
||||
u8 lcnphy_rssi_vf;
|
||||
u8 lcnphy_rssi_vc;
|
||||
u8 lcnphy_rssi_gs;
|
||||
u8 lcnphy_tssi_val;
|
||||
u8 lcnphy_rssi_vf_lowtemp;
|
||||
u8 lcnphy_rssi_vc_lowtemp;
|
||||
u8 lcnphy_rssi_gs_lowtemp;
|
||||
|
||||
u8 lcnphy_rssi_vf_hightemp;
|
||||
u8 lcnphy_rssi_vc_hightemp;
|
||||
u8 lcnphy_rssi_gs_hightemp;
|
||||
|
||||
s16 lcnphy_pa0b0;
|
||||
s16 lcnphy_pa0b1;
|
||||
s16 lcnphy_pa0b2;
|
||||
|
||||
u16 lcnphy_rawtempsense;
|
||||
u8 lcnphy_measPower;
|
||||
u8 lcnphy_tempsense_slope;
|
||||
u8 lcnphy_freqoffset_corr;
|
||||
u8 lcnphy_tempsense_option;
|
||||
u8 lcnphy_tempcorrx;
|
||||
bool lcnphy_iqcal_swp_dis;
|
||||
bool lcnphy_hw_iqcal_en;
|
||||
uint lcnphy_bandedge_corr;
|
||||
bool lcnphy_spurmod;
|
||||
u16 lcnphy_tssi_tx_cnt;
|
||||
u16 lcnphy_tssi_idx;
|
||||
u16 lcnphy_tssi_npt;
|
||||
|
||||
u16 lcnphy_target_tx_freq;
|
||||
s8 lcnphy_tx_power_idx_override;
|
||||
u16 lcnphy_noise_samples;
|
||||
|
||||
u32 lcnphy_papdRxGnIdx;
|
||||
u32 lcnphy_papd_rxGnCtrl_init;
|
||||
|
||||
u32 lcnphy_gain_idx_14_lowword;
|
||||
u32 lcnphy_gain_idx_14_hiword;
|
||||
u32 lcnphy_gain_idx_27_lowword;
|
||||
u32 lcnphy_gain_idx_27_hiword;
|
||||
s16 lcnphy_ofdmgainidxtableoffset;
|
||||
s16 lcnphy_dsssgainidxtableoffset;
|
||||
u32 lcnphy_tr_R_gain_val;
|
||||
u32 lcnphy_tr_T_gain_val;
|
||||
s8 lcnphy_input_pwr_offset_db;
|
||||
u16 lcnphy_Med_Low_Gain_db;
|
||||
u16 lcnphy_Very_Low_Gain_db;
|
||||
s8 lcnphy_lastsensed_temperature;
|
||||
s8 lcnphy_pkteng_rssi_slope;
|
||||
u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
|
||||
u8 lcnphy_volt_winner;
|
||||
u8 lcnphy_volt_low;
|
||||
u8 lcnphy_54_48_36_24mbps_backoff;
|
||||
u8 lcnphy_11n_backoff;
|
||||
u8 lcnphy_lowerofdm;
|
||||
u8 lcnphy_cck;
|
||||
u8 lcnphy_psat_2pt3_detected;
|
||||
s32 lcnphy_lowest_Re_div_Im;
|
||||
s8 lcnphy_final_papd_cal_idx;
|
||||
u16 lcnphy_extstxctrl4;
|
||||
u16 lcnphy_extstxctrl0;
|
||||
u16 lcnphy_extstxctrl1;
|
||||
s16 lcnphy_cck_dig_filt_type;
|
||||
s16 lcnphy_ofdm_dig_filt_type;
|
||||
struct lcnphy_cal_results lcnphy_cal_results;
|
||||
|
||||
u8 lcnphy_psat_pwr;
|
||||
u8 lcnphy_psat_indx;
|
||||
s32 lcnphy_min_phase;
|
||||
u8 lcnphy_final_idx;
|
||||
u8 lcnphy_start_idx;
|
||||
u8 lcnphy_current_index;
|
||||
u16 lcnphy_logen_buf_1;
|
||||
u16 lcnphy_local_ovr_2;
|
||||
u16 lcnphy_local_oval_6;
|
||||
u16 lcnphy_local_oval_5;
|
||||
u16 lcnphy_logen_mixer_1;
|
||||
|
||||
u8 lcnphy_aci_stat;
|
||||
uint lcnphy_aci_start_time;
|
||||
s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
|
||||
};
|
||||
#endif /* _BRCM_PHY_LCN_H_ */
|
28876
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
Normal file
28876
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
Normal file
File diff suppressed because it is too large
Load Diff
308
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
Normal file
308
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* 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 "phy_qmath.h"
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit unsigned multiplication.
|
||||
* To fit the output into 16 bits the 32 bit multiplication result is right
|
||||
* shifted by 16 bits.
|
||||
*/
|
||||
u16 qm_mulu16(u16 op1, u16 op2)
|
||||
{
|
||||
return (u16) (((u32) op1 * (u32) op2) >> 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit multiplication and return the result
|
||||
* in 16 bits. To fit the multiplication result into 16 bits the multiplication
|
||||
* result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits
|
||||
* is done to remove the extra sign bit formed due to the multiplication.
|
||||
* When both the 16bit inputs are 0x8000 then the output is saturated to
|
||||
* 0x7fffffff.
|
||||
*/
|
||||
s16 qm_muls16(s16 op1, s16 op2)
|
||||
{
|
||||
s32 result;
|
||||
if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000)
|
||||
result = 0x7fffffff;
|
||||
else
|
||||
result = ((s32) (op1) * (s32) (op2));
|
||||
|
||||
return (s16) (result >> 15);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function add two 32 bit numbers and return the 32bit
|
||||
* result. If the result overflow 32 bits, the output will be saturated to
|
||||
* 32bits.
|
||||
*/
|
||||
s32 qm_add32(s32 op1, s32 op2)
|
||||
{
|
||||
s32 result;
|
||||
result = op1 + op2;
|
||||
if (op1 < 0 && op2 < 0 && result > 0)
|
||||
result = 0x80000000;
|
||||
else if (op1 > 0 && op2 > 0 && result < 0)
|
||||
result = 0x7fffffff;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function add two 16 bit numbers and return the 16bit
|
||||
* result. If the result overflow 16 bits, the output will be saturated to
|
||||
* 16bits.
|
||||
*/
|
||||
s16 qm_add16(s16 op1, s16 op2)
|
||||
{
|
||||
s16 result;
|
||||
s32 temp = (s32) op1 + (s32) op2;
|
||||
if (temp > (s32) 0x7fff)
|
||||
result = (s16) 0x7fff;
|
||||
else if (temp < (s32) 0xffff8000)
|
||||
result = (s16) 0xffff8000;
|
||||
else
|
||||
result = (s16) temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit subtraction and return the 16bit
|
||||
* result. If the result overflow 16 bits, the output will be saturated to
|
||||
* 16bits.
|
||||
*/
|
||||
s16 qm_sub16(s16 op1, s16 op2)
|
||||
{
|
||||
s16 result;
|
||||
s32 temp = (s32) op1 - (s32) op2;
|
||||
if (temp > (s32) 0x7fff)
|
||||
result = (s16) 0x7fff;
|
||||
else if (temp < (s32) 0xffff8000)
|
||||
result = (s16) 0xffff8000;
|
||||
else
|
||||
result = (s16) temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 32 bit saturated left shift when the
|
||||
* specified shift is +ve. This function will make a 32 bit right shift when
|
||||
* the specified shift is -ve. This function return the result after shifting
|
||||
* operation.
|
||||
*/
|
||||
s32 qm_shl32(s32 op, int shift)
|
||||
{
|
||||
int i;
|
||||
s32 result;
|
||||
result = op;
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
else if (shift < -31)
|
||||
shift = -31;
|
||||
if (shift >= 0) {
|
||||
for (i = 0; i < shift; i++)
|
||||
result = qm_add32(result, result);
|
||||
} else {
|
||||
result = result >> (-shift);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 16 bit saturated left shift when the
|
||||
* specified shift is +ve. This function will make a 16 bit right shift when
|
||||
* the specified shift is -ve. This function return the result after shifting
|
||||
* operation.
|
||||
*/
|
||||
s16 qm_shl16(s16 op, int shift)
|
||||
{
|
||||
int i;
|
||||
s16 result;
|
||||
result = op;
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
else if (shift < -15)
|
||||
shift = -15;
|
||||
if (shift > 0) {
|
||||
for (i = 0; i < shift; i++)
|
||||
result = qm_add16(result, result);
|
||||
} else {
|
||||
result = result >> (-shift);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 16 bit right shift when shift is +ve.
|
||||
* This function make a 16 bit saturated left shift when shift is -ve. This
|
||||
* function return the result of the shift operation.
|
||||
*/
|
||||
s16 qm_shr16(s16 op, int shift)
|
||||
{
|
||||
return qm_shl16(op, -shift);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function return the number of redundant sign bits in a
|
||||
* 32 bit number. Example: qm_norm32(0x00000080) = 23
|
||||
*/
|
||||
s16 qm_norm32(s32 op)
|
||||
{
|
||||
u16 u16extraSignBits;
|
||||
if (op == 0) {
|
||||
return 31;
|
||||
} else {
|
||||
u16extraSignBits = 0;
|
||||
while ((op >> 31) == (op >> 30)) {
|
||||
u16extraSignBits++;
|
||||
op = op << 1;
|
||||
}
|
||||
}
|
||||
return u16extraSignBits;
|
||||
}
|
||||
|
||||
/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
|
||||
static const s16 log_table[] = {
|
||||
0,
|
||||
1455,
|
||||
2866,
|
||||
4236,
|
||||
5568,
|
||||
6863,
|
||||
8124,
|
||||
9352,
|
||||
10549,
|
||||
11716,
|
||||
12855,
|
||||
13968,
|
||||
15055,
|
||||
16117,
|
||||
17156,
|
||||
18173,
|
||||
19168,
|
||||
20143,
|
||||
21098,
|
||||
22034,
|
||||
22952,
|
||||
23852,
|
||||
24736,
|
||||
25604,
|
||||
26455,
|
||||
27292,
|
||||
28114,
|
||||
28922,
|
||||
29717,
|
||||
30498,
|
||||
31267,
|
||||
32024
|
||||
};
|
||||
|
||||
#define LOG_TABLE_SIZE 32 /* log_table size */
|
||||
#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */
|
||||
#define Q_LOG_TABLE 15 /* qformat of log_table */
|
||||
#define LOG10_2 19728 /* log10(2) in q.16 */
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* This routine takes the input number N and its q format qN and compute
|
||||
* the log10(N). This routine first normalizes the input no N. Then N is in
|
||||
* mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1).
|
||||
* Then log2(mag * 2^x) = log2(mag) + x is computed. From that
|
||||
* log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
|
||||
* This routine looks the log2 value in the table considering
|
||||
* LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next
|
||||
* LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used
|
||||
* for interpolation.
|
||||
* Inputs:
|
||||
* N - number to which log10 has to be found.
|
||||
* qN - q format of N
|
||||
* log10N - address where log10(N) will be written.
|
||||
* qLog10N - address where log10N qformat will be written.
|
||||
* Note/Problem:
|
||||
* For accurate results input should be in normalized or near normalized form.
|
||||
*/
|
||||
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
|
||||
{
|
||||
s16 s16norm, s16tableIndex, s16errorApproximation;
|
||||
u16 u16offset;
|
||||
s32 s32log;
|
||||
|
||||
/* normalize the N. */
|
||||
s16norm = qm_norm32(N);
|
||||
N = N << s16norm;
|
||||
|
||||
/* The qformat of N after normalization.
|
||||
* -30 is added to treat the no as between 1.0 to 2.0
|
||||
* i.e. after adding the -30 to the qformat the decimal point will be
|
||||
* just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
|
||||
* at the right side of 30th bit.
|
||||
*/
|
||||
qN = qN + s16norm - 30;
|
||||
|
||||
/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the
|
||||
* MSB */
|
||||
s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
|
||||
|
||||
/* remove the MSB. the MSB is always 1 after normalization. */
|
||||
s16tableIndex =
|
||||
s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
|
||||
|
||||
/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
|
||||
N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
|
||||
|
||||
/* take the offset as the 16 MSBS after table index.
|
||||
*/
|
||||
u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
|
||||
|
||||
/* look the log value in the table. */
|
||||
s32log = log_table[s16tableIndex]; /* q.15 format */
|
||||
|
||||
/* interpolate using the offset. q.15 format. */
|
||||
s16errorApproximation = (s16) qm_mulu16(u16offset,
|
||||
(u16) (log_table[s16tableIndex + 1] -
|
||||
log_table[s16tableIndex]));
|
||||
|
||||
/* q.15 format */
|
||||
s32log = qm_add16((s16) s32log, s16errorApproximation);
|
||||
|
||||
/* adjust for the qformat of the N as
|
||||
* log2(mag * 2^x) = log2(mag) + x
|
||||
*/
|
||||
s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */
|
||||
|
||||
/* normalize the result. */
|
||||
s16norm = qm_norm32(s32log);
|
||||
|
||||
/* bring all the important bits into lower 16 bits */
|
||||
/* q.15+s16norm-16 format */
|
||||
s32log = qm_shl32(s32log, s16norm - 16);
|
||||
|
||||
/* compute the log10(N) by multiplying log2(N) with log10(2).
|
||||
* as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
|
||||
* log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
|
||||
*/
|
||||
*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
|
||||
|
||||
/* write the q format of the result. */
|
||||
*qLog10N = 15 + s16norm - 16 + 1;
|
||||
|
||||
return;
|
||||
}
|
42
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
Normal file
42
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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_QMATH_H_
|
||||
#define _BRCM_QMATH_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
u16 qm_mulu16(u16 op1, u16 op2);
|
||||
|
||||
s16 qm_muls16(s16 op1, s16 op2);
|
||||
|
||||
s32 qm_add32(s32 op1, s32 op2);
|
||||
|
||||
s16 qm_add16(s16 op1, s16 op2);
|
||||
|
||||
s16 qm_sub16(s16 op1, s16 op2);
|
||||
|
||||
s32 qm_shl32(s32 op, int shift);
|
||||
|
||||
s16 qm_shl16(s16 op, int shift);
|
||||
|
||||
s16 qm_shr16(s16 op, int shift);
|
||||
|
||||
s16 qm_norm32(s32 op);
|
||||
|
||||
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
|
||||
|
||||
#endif /* #ifndef _BRCM_QMATH_H_ */
|
1533
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
Normal file
1533
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
Normal file
File diff suppressed because it is too large
Load Diff
167
drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
Normal file
167
drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define NPHY_TBL_ID_GAIN1 0
|
||||
#define NPHY_TBL_ID_GAIN2 1
|
||||
#define NPHY_TBL_ID_GAINBITS1 2
|
||||
#define NPHY_TBL_ID_GAINBITS2 3
|
||||
#define NPHY_TBL_ID_GAINLIMIT 4
|
||||
#define NPHY_TBL_ID_WRSSIGainLimit 5
|
||||
#define NPHY_TBL_ID_RFSEQ 7
|
||||
#define NPHY_TBL_ID_AFECTRL 8
|
||||
#define NPHY_TBL_ID_ANTSWCTRLLUT 9
|
||||
#define NPHY_TBL_ID_IQLOCAL 15
|
||||
#define NPHY_TBL_ID_NOISEVAR 16
|
||||
#define NPHY_TBL_ID_SAMPLEPLAY 17
|
||||
#define NPHY_TBL_ID_CORE1TXPWRCTL 26
|
||||
#define NPHY_TBL_ID_CORE2TXPWRCTL 27
|
||||
#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30
|
||||
|
||||
#define NPHY_TBL_ID_EPSILONTBL0 31
|
||||
#define NPHY_TBL_ID_SCALARTBL0 32
|
||||
#define NPHY_TBL_ID_EPSILONTBL1 33
|
||||
#define NPHY_TBL_ID_SCALARTBL1 34
|
||||
|
||||
#define NPHY_TO_BPHY_OFF 0xc00
|
||||
|
||||
#define NPHY_BandControl_currentBand 0x0001
|
||||
#define RFCC_CHIP0_PU 0x0400
|
||||
#define RFCC_POR_FORCE 0x0040
|
||||
#define RFCC_OE_POR_FORCE 0x0080
|
||||
#define NPHY_RfctrlIntc_override_OFF 0
|
||||
#define NPHY_RfctrlIntc_override_TRSW 1
|
||||
#define NPHY_RfctrlIntc_override_PA 2
|
||||
#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3
|
||||
#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4
|
||||
#define RIFS_ENABLE 0x80
|
||||
#define BPHY_BAND_SEL_UP20 0x10
|
||||
#define NPHY_MLenable 0x02
|
||||
|
||||
#define NPHY_RfseqMode_CoreActv_override 0x0001
|
||||
#define NPHY_RfseqMode_Trigger_override 0x0002
|
||||
#define NPHY_RfseqCoreActv_TxRxChain0 (0x11)
|
||||
#define NPHY_RfseqCoreActv_TxRxChain1 (0x22)
|
||||
|
||||
#define NPHY_RfseqTrigger_rx2tx 0x0001
|
||||
#define NPHY_RfseqTrigger_tx2rx 0x0002
|
||||
#define NPHY_RfseqTrigger_updategainh 0x0004
|
||||
#define NPHY_RfseqTrigger_updategainl 0x0008
|
||||
#define NPHY_RfseqTrigger_updategainu 0x0010
|
||||
#define NPHY_RfseqTrigger_reset2rx 0x0020
|
||||
#define NPHY_RfseqStatus_rx2tx 0x0001
|
||||
#define NPHY_RfseqStatus_tx2rx 0x0002
|
||||
#define NPHY_RfseqStatus_updategainh 0x0004
|
||||
#define NPHY_RfseqStatus_updategainl 0x0008
|
||||
#define NPHY_RfseqStatus_updategainu 0x0010
|
||||
#define NPHY_RfseqStatus_reset2rx 0x0020
|
||||
#define NPHY_ClassifierCtrl_cck_en 0x1
|
||||
#define NPHY_ClassifierCtrl_ofdm_en 0x2
|
||||
#define NPHY_ClassifierCtrl_waited_en 0x4
|
||||
#define NPHY_IQFlip_ADC1 0x0001
|
||||
#define NPHY_IQFlip_ADC2 0x0010
|
||||
#define NPHY_sampleCmd_STOP 0x0002
|
||||
|
||||
#define RX_GF_OR_MM 0x0004
|
||||
#define RX_GF_MM_AUTO 0x0100
|
||||
|
||||
#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000
|
||||
|
||||
#define NPHY_IqestCmd_iqstart 0x1
|
||||
#define NPHY_IqestCmd_iqMode 0x2
|
||||
|
||||
#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40
|
||||
#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19
|
||||
|
||||
#define PRIM_SEL_UP20 0x8000
|
||||
|
||||
#define NPHY_RFSEQ_RX2TX 0x0
|
||||
#define NPHY_RFSEQ_TX2RX 0x1
|
||||
#define NPHY_RFSEQ_RESET2RX 0x2
|
||||
#define NPHY_RFSEQ_UPDATEGAINH 0x3
|
||||
#define NPHY_RFSEQ_UPDATEGAINL 0x4
|
||||
#define NPHY_RFSEQ_UPDATEGAINU 0x5
|
||||
|
||||
#define NPHY_RFSEQ_CMD_NOP 0x0
|
||||
#define NPHY_RFSEQ_CMD_RXG_FBW 0x1
|
||||
#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2
|
||||
#define NPHY_RFSEQ_CMD_EXT_PA 0x3
|
||||
#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4
|
||||
#define NPHY_RFSEQ_CMD_TX_GAIN 0x5
|
||||
#define NPHY_RFSEQ_CMD_RX_GAIN 0x6
|
||||
#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7
|
||||
#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8
|
||||
#define NPHY_RFSEQ_CMD_END 0xf
|
||||
|
||||
#define NPHY_REV3_RFSEQ_CMD_NOP 0x0
|
||||
#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1
|
||||
#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2
|
||||
#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3
|
||||
#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4
|
||||
#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5
|
||||
#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6
|
||||
#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7
|
||||
#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe
|
||||
#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf
|
||||
#define NPHY_REV3_RFSEQ_CMD_END 0x1f
|
||||
|
||||
#define NPHY_RSSI_SEL_W1 0x0
|
||||
#define NPHY_RSSI_SEL_W2 0x1
|
||||
#define NPHY_RSSI_SEL_NB 0x2
|
||||
#define NPHY_RSSI_SEL_IQ 0x3
|
||||
#define NPHY_RSSI_SEL_TSSI_2G 0x4
|
||||
#define NPHY_RSSI_SEL_TSSI_5G 0x5
|
||||
#define NPHY_RSSI_SEL_TBD 0x6
|
||||
|
||||
#define NPHY_RAIL_I 0x0
|
||||
#define NPHY_RAIL_Q 0x1
|
||||
|
||||
#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8
|
||||
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4
|
||||
|
||||
#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
|
||||
#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00
|
||||
#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
|
||||
|
||||
#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff
|
||||
#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000
|
||||
#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
|
||||
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
|
||||
|
||||
#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134)
|
||||
|
||||
#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135)
|
||||
|
||||
#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136)
|
||||
|
||||
#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137)
|
||||
|
||||
#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138)
|
||||
|
||||
#define NPHY_IqestqpwrAccHi(core) ((core == 0) ? 0x131 : 0x139)
|
3250
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
Normal file
3250
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
Normal file
File diff suppressed because it is too large
Load Diff
54
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
Normal file
54
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 <types.h>
|
||||
#include "phy_int.h"
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
|
||||
extern const u32 dot11lcnphytbl_info_sz_rev0;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
|
||||
|
||||
struct lcnphy_tx_gain_tbl_entry {
|
||||
unsigned char gm;
|
||||
unsigned char pga;
|
||||
unsigned char pad;
|
||||
unsigned char dac;
|
||||
unsigned char bb_mult;
|
||||
};
|
||||
|
||||
extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
|
||||
|
||||
extern const struct
|
||||
lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
|
||||
|
||||
extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
|
10630
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
Normal file
10630
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
Normal file
File diff suppressed because it is too large
Load Diff
50
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
Normal file
50
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define ANT_SWCTRL_TBL_REV3_IDX (0)
|
||||
|
||||
#include <types.h>
|
||||
#include "phy_int.h"
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev0[],
|
||||
mimophytbl_info_rev0_volatile[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev0,
|
||||
mimophytbl_info_sz_rev0_volatile;
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev3[],
|
||||
mimophytbl_info_rev3_volatile[],
|
||||
mimophytbl_info_rev3_volatile1[],
|
||||
mimophytbl_info_rev3_volatile2[],
|
||||
mimophytbl_info_rev3_volatile3[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev3,
|
||||
mimophytbl_info_sz_rev3_volatile,
|
||||
mimophytbl_info_sz_rev3_volatile1,
|
||||
mimophytbl_info_sz_rev3_volatile2,
|
||||
mimophytbl_info_sz_rev3_volatile3;
|
||||
|
||||
extern const u32 noise_var_tbl_rev3[];
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev7[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev7;
|
||||
|
||||
extern const u32 noise_var_tbl_rev7[];
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev16[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev16;
|
226
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
Normal file
226
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is "two-way" interface, acting as the SHIM layer between driver
|
||||
* and PHY layer. The driver can optionally call this translation layer
|
||||
* to do some preprocessing, then reach PHY. On the PHY->driver direction,
|
||||
* all calls go through this layer since PHY doesn't have access to the
|
||||
* driver's brcms_hardware pointer.
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "mac80211_if.h"
|
||||
#include "phy_shim.h"
|
||||
|
||||
/* PHY SHIM module specific state */
|
||||
struct phy_shim_info {
|
||||
struct brcms_hardware *wlc_hw; /* pointer to main wlc_hw structure */
|
||||
struct brcms_c_info *wlc; /* pointer to main wlc structure */
|
||||
struct brcms_info *wl; /* pointer to os-specific private state */
|
||||
};
|
||||
|
||||
struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
|
||||
struct brcms_info *wl,
|
||||
struct brcms_c_info *wlc) {
|
||||
struct phy_shim_info *physhim = NULL;
|
||||
|
||||
physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
|
||||
if (!physhim)
|
||||
return NULL;
|
||||
|
||||
physhim->wlc_hw = wlc_hw;
|
||||
physhim->wlc = wlc;
|
||||
physhim->wl = wl;
|
||||
|
||||
return physhim;
|
||||
}
|
||||
|
||||
void wlc_phy_shim_detach(struct phy_shim_info *physhim)
|
||||
{
|
||||
kfree(physhim);
|
||||
}
|
||||
|
||||
struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
|
||||
void (*fn)(struct brcms_phy *pi),
|
||||
void *arg, const char *name)
|
||||
{
|
||||
return (struct wlapi_timer *)
|
||||
brcms_init_timer(physhim->wl, (void (*)(void *))fn,
|
||||
arg, name);
|
||||
}
|
||||
|
||||
void wlapi_free_timer(struct phy_shim_info *physhim, struct wlapi_timer *t)
|
||||
{
|
||||
brcms_free_timer(physhim->wl, (struct brcms_timer *)t);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_add_timer(struct phy_shim_info *physhim, struct wlapi_timer *t, uint ms,
|
||||
int periodic)
|
||||
{
|
||||
brcms_add_timer(physhim->wl, (struct brcms_timer *)t, ms, periodic);
|
||||
}
|
||||
|
||||
bool wlapi_del_timer(struct phy_shim_info *physhim, struct wlapi_timer *t)
|
||||
{
|
||||
return brcms_del_timer(physhim->wl, (struct brcms_timer *)t);
|
||||
}
|
||||
|
||||
void wlapi_intrson(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_intrson(physhim->wl);
|
||||
}
|
||||
|
||||
u32 wlapi_intrsoff(struct phy_shim_info *physhim)
|
||||
{
|
||||
return brcms_intrsoff(physhim->wl);
|
||||
}
|
||||
|
||||
void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
|
||||
{
|
||||
brcms_intrsrestore(physhim->wl, macintmask);
|
||||
}
|
||||
|
||||
void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
|
||||
{
|
||||
brcms_b_write_shm(physhim->wlc_hw, offset, v);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
|
||||
{
|
||||
return brcms_b_read_shm(physhim->wlc_hw, offset);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
|
||||
u16 val, int bands)
|
||||
{
|
||||
brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
|
||||
}
|
||||
|
||||
void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
|
||||
{
|
||||
brcms_b_corereset(physhim->wlc_hw, flags);
|
||||
}
|
||||
|
||||
void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_suspend_mac_and_wait(physhim->wlc);
|
||||
}
|
||||
|
||||
void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
|
||||
{
|
||||
brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
|
||||
}
|
||||
|
||||
void wlapi_enable_mac(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_enable_mac(physhim->wlc);
|
||||
}
|
||||
|
||||
void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
|
||||
{
|
||||
brcms_b_mctrl(physhim->wlc_hw, mask, val);
|
||||
}
|
||||
|
||||
void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_b_phy_reset(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
|
||||
{
|
||||
brcms_b_bw_set(physhim->wlc_hw, bw);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
|
||||
{
|
||||
return brcms_b_get_txant(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
|
||||
{
|
||||
brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
|
||||
}
|
||||
|
||||
void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
|
||||
{
|
||||
brcms_b_macphyclk_set(physhim->wlc_hw, clk);
|
||||
}
|
||||
|
||||
void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
|
||||
{
|
||||
brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
|
||||
}
|
||||
|
||||
void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_b_core_phypll_reset(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_ucode_wake_override_set(physhim->wlc_hw,
|
||||
BRCMS_WAKE_OVERRIDE_PHYREG);
|
||||
}
|
||||
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
|
||||
BRCMS_WAKE_OVERRIDE_PHYREG);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
|
||||
int len, void *buf)
|
||||
{
|
||||
brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
|
||||
{
|
||||
return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
|
||||
}
|
||||
|
||||
void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
|
||||
int len, u32 sel)
|
||||
{
|
||||
brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
|
||||
int l, u32 sel)
|
||||
{
|
||||
brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
|
||||
}
|
||||
|
||||
char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
|
||||
{
|
||||
return getvar(physhim->wlc_hw->sih, id);
|
||||
}
|
||||
int wlapi_getintvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
|
||||
{
|
||||
return getintvar(physhim->wlc_hw->sih, id);
|
||||
}
|
185
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
Normal file
185
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* phy_shim.h: stuff defined in phy_shim.c and included only by the phy
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PHY_SHIM_H_
|
||||
#define _BRCM_PHY_SHIM_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define RADAR_TYPE_NONE 0 /* Radar type None */
|
||||
#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */
|
||||
#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */
|
||||
#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */
|
||||
#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */
|
||||
#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */
|
||||
#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */
|
||||
#define RADAR_TYPE_BIN5 7 /* long pulse radar type */
|
||||
#define RADAR_TYPE_STG2 8 /* staggered-2 radar */
|
||||
#define RADAR_TYPE_STG3 9 /* staggered-3 radar */
|
||||
#define RADAR_TYPE_FRA 10 /* French radar */
|
||||
|
||||
/* French radar pulse widths */
|
||||
#define FRA_T1_20MHZ 52770
|
||||
#define FRA_T2_20MHZ 61538
|
||||
#define FRA_T3_20MHZ 66002
|
||||
#define FRA_T1_40MHZ 105541
|
||||
#define FRA_T2_40MHZ 123077
|
||||
#define FRA_T3_40MHZ 132004
|
||||
#define FRA_ERR_20MHZ 60
|
||||
#define FRA_ERR_40MHZ 120
|
||||
|
||||
#define ANTSEL_NA 0 /* No boardlevel selection available */
|
||||
#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */
|
||||
#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */
|
||||
|
||||
/* Rx Antenna diversity control values */
|
||||
#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
|
||||
#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
|
||||
#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
|
||||
#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
|
||||
#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
|
||||
#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
|
||||
|
||||
#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */
|
||||
#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */
|
||||
#define WL_ANT_IDX_1 0 /* antenna index 1 */
|
||||
#define WL_ANT_IDX_2 1 /* antenna index 2 */
|
||||
|
||||
/* values for n_preamble_type */
|
||||
#define BRCMS_N_PREAMBLE_MIXEDMODE 0
|
||||
#define BRCMS_N_PREAMBLE_GF 1
|
||||
#define BRCMS_N_PREAMBLE_GF_BRCM 2
|
||||
|
||||
#define WL_TX_POWER_RATES_LEGACY 45
|
||||
#define WL_TX_POWER_MCS20_FIRST 12
|
||||
#define WL_TX_POWER_MCS20_NUM 16
|
||||
#define WL_TX_POWER_MCS40_FIRST 28
|
||||
#define WL_TX_POWER_MCS40_NUM 17
|
||||
|
||||
|
||||
#define WL_TX_POWER_RATES 101
|
||||
#define WL_TX_POWER_CCK_FIRST 0
|
||||
#define WL_TX_POWER_CCK_NUM 4
|
||||
/* Index for first 20MHz OFDM SISO rate */
|
||||
#define WL_TX_POWER_OFDM_FIRST 4
|
||||
/* Index for first 20MHz OFDM CDD rate */
|
||||
#define WL_TX_POWER_OFDM20_CDD_FIRST 12
|
||||
/* Index for first 40MHz OFDM SISO rate */
|
||||
#define WL_TX_POWER_OFDM40_SISO_FIRST 52
|
||||
/* Index for first 40MHz OFDM CDD rate */
|
||||
#define WL_TX_POWER_OFDM40_CDD_FIRST 60
|
||||
#define WL_TX_POWER_OFDM_NUM 8
|
||||
/* Index for first 20MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS20_SISO_FIRST 20
|
||||
/* Index for first 20MHz MCS CDD rate */
|
||||
#define WL_TX_POWER_MCS20_CDD_FIRST 28
|
||||
/* Index for first 20MHz MCS STBC rate */
|
||||
#define WL_TX_POWER_MCS20_STBC_FIRST 36
|
||||
/* Index for first 20MHz MCS SDM rate */
|
||||
#define WL_TX_POWER_MCS20_SDM_FIRST 44
|
||||
/* Index for first 40MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS40_SISO_FIRST 68
|
||||
/* Index for first 40MHz MCS CDD rate */
|
||||
#define WL_TX_POWER_MCS40_CDD_FIRST 76
|
||||
/* Index for first 40MHz MCS STBC rate */
|
||||
#define WL_TX_POWER_MCS40_STBC_FIRST 84
|
||||
/* Index for first 40MHz MCS SDM rate */
|
||||
#define WL_TX_POWER_MCS40_SDM_FIRST 92
|
||||
#define WL_TX_POWER_MCS_1_STREAM_NUM 8
|
||||
#define WL_TX_POWER_MCS_2_STREAM_NUM 8
|
||||
/* Index for 40MHz rate MCS 32 */
|
||||
#define WL_TX_POWER_MCS_32 100
|
||||
#define WL_TX_POWER_MCS_32_NUM 1
|
||||
|
||||
/* sslpnphy specifics */
|
||||
/* Index for first 20MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12
|
||||
|
||||
/* struct tx_power::flags bits */
|
||||
#define WL_TX_POWER_F_ENABLED 1
|
||||
#define WL_TX_POWER_F_HW 2
|
||||
#define WL_TX_POWER_F_MIMO 4
|
||||
#define WL_TX_POWER_F_SISO 8
|
||||
|
||||
/* values to force tx/rx chain */
|
||||
#define BRCMS_N_TXRX_CHAIN0 0
|
||||
#define BRCMS_N_TXRX_CHAIN1 1
|
||||
|
||||
struct brcms_phy;
|
||||
|
||||
extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
|
||||
struct brcms_info *wl,
|
||||
struct brcms_c_info *wlc);
|
||||
extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
|
||||
|
||||
/* PHY to WL utility functions */
|
||||
extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
|
||||
void (*fn) (struct brcms_phy *pi),
|
||||
void *arg, const char *name);
|
||||
extern void wlapi_free_timer(struct phy_shim_info *physhim,
|
||||
struct wlapi_timer *t);
|
||||
extern void wlapi_add_timer(struct phy_shim_info *physhim,
|
||||
struct wlapi_timer *t, uint ms, int periodic);
|
||||
extern bool wlapi_del_timer(struct phy_shim_info *physhim,
|
||||
struct wlapi_timer *t);
|
||||
extern void wlapi_intrson(struct phy_shim_info *physhim);
|
||||
extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
|
||||
extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
|
||||
u32 macintmask);
|
||||
|
||||
extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset,
|
||||
u16 v);
|
||||
extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
|
||||
extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx,
|
||||
u16 mask, u16 val, int bands);
|
||||
extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
|
||||
extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
|
||||
extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
|
||||
extern void wlapi_enable_mac(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask,
|
||||
u32 val);
|
||||
extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
|
||||
extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
|
||||
extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
|
||||
extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
|
||||
extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *
|
||||
physhim);
|
||||
extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *
|
||||
physhim);
|
||||
extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
|
||||
int len, void *buf);
|
||||
extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim,
|
||||
u8 rate);
|
||||
extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
|
||||
extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint,
|
||||
void *buf, int, u32 sel);
|
||||
extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
|
||||
const void *buf, int, u32);
|
||||
|
||||
extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
|
||||
u32 phy_mode);
|
||||
extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
|
||||
extern char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id);
|
||||
extern int wlapi_getintvar(struct phy_shim_info *physhim,
|
||||
enum brcms_srom_id id);
|
||||
|
||||
#endif /* _BRCM_PHY_SHIM_H_ */
|
458
drivers/net/wireless/brcm80211/brcmsmac/pmu.c
Normal file
458
drivers/net/wireless/brcm80211/brcmsmac/pmu.c
Normal file
@ -0,0 +1,458 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <chipcommon.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include "pub.h"
|
||||
#include "aiutils.h"
|
||||
#include "pmu.h"
|
||||
|
||||
/*
|
||||
* external LPO crystal frequency
|
||||
*/
|
||||
#define EXT_ILP_HZ 32768
|
||||
|
||||
/*
|
||||
* Duration for ILP clock frequency measurment in milliseconds
|
||||
*
|
||||
* remark: 1000 must be an integer multiple of this duration
|
||||
*/
|
||||
#define ILP_CALC_DUR 10
|
||||
|
||||
/* Fields in pmucontrol */
|
||||
#define PCTL_ILP_DIV_MASK 0xffff0000
|
||||
#define PCTL_ILP_DIV_SHIFT 16
|
||||
#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */
|
||||
#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */
|
||||
#define PCTL_HT_REQ_EN 0x00000100
|
||||
#define PCTL_ALP_REQ_EN 0x00000080
|
||||
#define PCTL_XTALFREQ_MASK 0x0000007c
|
||||
#define PCTL_XTALFREQ_SHIFT 2
|
||||
#define PCTL_ILP_DIV_EN 0x00000002
|
||||
#define PCTL_LPO_SEL 0x00000001
|
||||
|
||||
/* ILP clock */
|
||||
#define ILP_CLOCK 32000
|
||||
|
||||
/* ALP clock on pre-PMU chips */
|
||||
#define ALP_CLOCK 20000000
|
||||
|
||||
/* pmustatus */
|
||||
#define PST_EXTLPOAVAIL 0x0100
|
||||
#define PST_WDRESET 0x0080
|
||||
#define PST_INTPEND 0x0040
|
||||
#define PST_SBCLKST 0x0030
|
||||
#define PST_SBCLKST_ILP 0x0010
|
||||
#define PST_SBCLKST_ALP 0x0020
|
||||
#define PST_SBCLKST_HT 0x0030
|
||||
#define PST_ALPAVAIL 0x0008
|
||||
#define PST_HTAVAIL 0x0004
|
||||
#define PST_RESINIT 0x0003
|
||||
|
||||
/* PMU resource bit position */
|
||||
#define PMURES_BIT(bit) (1 << (bit))
|
||||
|
||||
/* PMU corerev and chip specific PLL controls.
|
||||
* PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
|
||||
* number to differentiate different PLLs controlled by the same PMU rev.
|
||||
*/
|
||||
/* pllcontrol registers:
|
||||
* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>,
|
||||
* p1div, p2div, _bypass_sdmod
|
||||
*/
|
||||
#define PMU1_PLL0_PLLCTL0 0
|
||||
#define PMU1_PLL0_PLLCTL1 1
|
||||
#define PMU1_PLL0_PLLCTL2 2
|
||||
#define PMU1_PLL0_PLLCTL3 3
|
||||
#define PMU1_PLL0_PLLCTL4 4
|
||||
#define PMU1_PLL0_PLLCTL5 5
|
||||
|
||||
/* pmu XtalFreqRatio */
|
||||
#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF
|
||||
#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000
|
||||
#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31
|
||||
|
||||
/* 4313 resources */
|
||||
#define RES4313_BB_PU_RSRC 0
|
||||
#define RES4313_ILP_REQ_RSRC 1
|
||||
#define RES4313_XTAL_PU_RSRC 2
|
||||
#define RES4313_ALP_AVAIL_RSRC 3
|
||||
#define RES4313_RADIO_PU_RSRC 4
|
||||
#define RES4313_BG_PU_RSRC 5
|
||||
#define RES4313_VREG1P4_PU_RSRC 6
|
||||
#define RES4313_AFE_PWRSW_RSRC 7
|
||||
#define RES4313_RX_PWRSW_RSRC 8
|
||||
#define RES4313_TX_PWRSW_RSRC 9
|
||||
#define RES4313_BB_PWRSW_RSRC 10
|
||||
#define RES4313_SYNTH_PWRSW_RSRC 11
|
||||
#define RES4313_MISC_PWRSW_RSRC 12
|
||||
#define RES4313_BB_PLL_PWRSW_RSRC 13
|
||||
#define RES4313_HT_AVAIL_RSRC 14
|
||||
#define RES4313_MACPHY_CLK_AVAIL_RSRC 15
|
||||
|
||||
/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
|
||||
static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
|
||||
{
|
||||
u32 min_mask = 0, max_mask = 0;
|
||||
uint rsrcs;
|
||||
|
||||
/* # resources */
|
||||
rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
|
||||
|
||||
/* determine min/max rsrc masks */
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
/* ??? */
|
||||
break;
|
||||
|
||||
case BCM4313_CHIP_ID:
|
||||
min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
|
||||
PMURES_BIT(RES4313_XTAL_PU_RSRC) |
|
||||
PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
|
||||
PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
|
||||
max_mask = 0xffff;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*pmin = min_mask;
|
||||
*pmax = max_mask;
|
||||
}
|
||||
|
||||
static void
|
||||
si_pmu_spuravoid_pllupdate(struct si_pub *sih, struct chipcregs __iomem *cc,
|
||||
u8 spuravoid)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
if (spuravoid == 1) {
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11500010);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x000C0C06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x0F600a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x2001E920);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888815);
|
||||
} else {
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11100010);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x000c0c06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x03000a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x200005c0);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888815);
|
||||
}
|
||||
tmp = 1 << 10;
|
||||
break;
|
||||
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11100008);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x0c000c06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x03000a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x200005c0);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888855);
|
||||
|
||||
tmp = 1 << 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* bail out */
|
||||
return;
|
||||
}
|
||||
|
||||
tmp |= R_REG(&cc->pmucontrol);
|
||||
W_REG(&cc->pmucontrol, tmp);
|
||||
}
|
||||
|
||||
u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
|
||||
{
|
||||
uint delay = PMU_MAX_TRANSITION_DLY;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
case BCM4313_CHIP_ID:
|
||||
delay = 3700;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (u16) delay;
|
||||
}
|
||||
|
||||
void si_pmu_sprom_enable(struct si_pub *sih, bool enable)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* Read/write a chipcontrol reg */
|
||||
u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data), mask,
|
||||
val);
|
||||
}
|
||||
|
||||
/* Read/write a regcontrol reg */
|
||||
u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, regcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, regcontrol_data), mask,
|
||||
val);
|
||||
}
|
||||
|
||||
/* Read/write a pllcontrol reg */
|
||||
u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pllcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, pllcontrol_data), mask,
|
||||
val);
|
||||
}
|
||||
|
||||
/* PMU PLL update */
|
||||
void si_pmu_pllupd(struct si_pub *sih)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pmucontrol),
|
||||
PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
|
||||
}
|
||||
|
||||
/* query alp/xtal clock frequency */
|
||||
u32 si_pmu_alp_clock(struct si_pub *sih)
|
||||
{
|
||||
u32 clock = ALP_CLOCK;
|
||||
|
||||
/* bail out with default */
|
||||
if (!(sih->cccaps & CC_CAP_PMU))
|
||||
return clock;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
case BCM4313_CHIP_ID:
|
||||
/* always 20Mhz */
|
||||
clock = 20000 * 1000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx, intr_val;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
cc = (struct chipcregs __iomem *)
|
||||
ai_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
|
||||
|
||||
/* update the pll changes */
|
||||
si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
|
||||
|
||||
/* Return to original core */
|
||||
ai_restore_core(sih, origidx, intr_val);
|
||||
}
|
||||
|
||||
/* initialize PMU */
|
||||
void si_pmu_init(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
if (sih->pmurev == 1)
|
||||
AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
|
||||
else if (sih->pmurev >= 2)
|
||||
OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU chip controls and other chip level stuff */
|
||||
void si_pmu_chip_init(struct si_pub *sih)
|
||||
{
|
||||
uint origidx;
|
||||
|
||||
/* Gate off SPROM clock and chip select signals */
|
||||
si_pmu_sprom_enable(sih, false);
|
||||
|
||||
/* Remember original core */
|
||||
origidx = ai_coreidx(sih);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU switch/regulators */
|
||||
void si_pmu_swreg_init(struct si_pub *sih)
|
||||
{
|
||||
}
|
||||
|
||||
/* initialize PLL */
|
||||
void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM4313_CHIP_ID:
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
/* ??? */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU resources */
|
||||
void si_pmu_res_init(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
u32 min_mask = 0, max_mask = 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
/* Determine min/max rsrc masks */
|
||||
si_pmu_res_masks(sih, &min_mask, &max_mask);
|
||||
|
||||
/* It is required to program max_mask first and then min_mask */
|
||||
|
||||
/* Program max resource mask */
|
||||
|
||||
if (max_mask)
|
||||
W_REG(&cc->max_res_mask, max_mask);
|
||||
|
||||
/* Program min resource mask */
|
||||
|
||||
if (min_mask)
|
||||
W_REG(&cc->min_res_mask, min_mask);
|
||||
|
||||
/* Add some delay; allow resources to come up and settle. */
|
||||
mdelay(2);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
u32 si_pmu_measure_alpclk(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
u32 alp_khz;
|
||||
|
||||
if (sih->pmurev < 10)
|
||||
return 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
|
||||
u32 ilp_ctr, alp_hz;
|
||||
|
||||
/*
|
||||
* Enable the reg to measure the freq,
|
||||
* in case it was disabled before
|
||||
*/
|
||||
W_REG(&cc->pmu_xtalfreq,
|
||||
1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
|
||||
|
||||
/* Delay for well over 4 ILP clocks */
|
||||
udelay(1000);
|
||||
|
||||
/* Read the latched number of ALP ticks per 4 ILP ticks */
|
||||
ilp_ctr =
|
||||
R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
|
||||
|
||||
/*
|
||||
* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
|
||||
* bit to save power
|
||||
*/
|
||||
W_REG(&cc->pmu_xtalfreq, 0);
|
||||
|
||||
/* Calculate ALP frequency */
|
||||
alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
|
||||
|
||||
/*
|
||||
* Round to nearest 100KHz, and at
|
||||
* the same time convert to KHz
|
||||
*/
|
||||
alp_khz = (alp_hz + 50000) / 100000 * 100;
|
||||
} else
|
||||
alp_khz = 0;
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
|
||||
return alp_khz;
|
||||
}
|
38
drivers/net/wireless/brcm80211/brcmsmac/pmu.h
Normal file
38
drivers/net/wireless/brcm80211/brcmsmac/pmu.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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_PMU_H_
|
||||
#define _BRCM_PMU_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
|
||||
extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable);
|
||||
extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern u32 si_pmu_alp_clock(struct si_pub *sih);
|
||||
extern void si_pmu_pllupd(struct si_pub *sih);
|
||||
extern void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid);
|
||||
extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern void si_pmu_init(struct si_pub *sih);
|
||||
extern void si_pmu_chip_init(struct si_pub *sih);
|
||||
extern void si_pmu_pll_init(struct si_pub *sih, u32 xtalfreq);
|
||||
extern void si_pmu_res_init(struct si_pub *sih);
|
||||
extern void si_pmu_swreg_init(struct si_pub *sih);
|
||||
extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
|
||||
|
||||
#endif /* _BRCM_PMU_H_ */
|
655
drivers/net/wireless/brcm80211/brcmsmac/pub.h
Normal file
655
drivers/net/wireless/brcm80211/brcmsmac/pub.h
Normal file
@ -0,0 +1,655 @@
|
||||
/*
|
||||
* 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_PUB_H_
|
||||
#define _BRCM_PUB_H_
|
||||
|
||||
#include <brcmu_wifi.h>
|
||||
#include "types.h"
|
||||
#include "defs.h"
|
||||
|
||||
enum brcms_srom_id {
|
||||
BRCMS_SROM_NULL,
|
||||
BRCMS_SROM_CONT,
|
||||
BRCMS_SROM_AA2G,
|
||||
BRCMS_SROM_AA5G,
|
||||
BRCMS_SROM_AG0,
|
||||
BRCMS_SROM_AG1,
|
||||
BRCMS_SROM_AG2,
|
||||
BRCMS_SROM_AG3,
|
||||
BRCMS_SROM_ANTSWCTL2G,
|
||||
BRCMS_SROM_ANTSWCTL5G,
|
||||
BRCMS_SROM_ANTSWITCH,
|
||||
BRCMS_SROM_BOARDFLAGS2,
|
||||
BRCMS_SROM_BOARDFLAGS,
|
||||
BRCMS_SROM_BOARDNUM,
|
||||
BRCMS_SROM_BOARDREV,
|
||||
BRCMS_SROM_BOARDTYPE,
|
||||
BRCMS_SROM_BW40PO,
|
||||
BRCMS_SROM_BWDUPPO,
|
||||
BRCMS_SROM_BXA2G,
|
||||
BRCMS_SROM_BXA5G,
|
||||
BRCMS_SROM_CC,
|
||||
BRCMS_SROM_CCK2GPO,
|
||||
BRCMS_SROM_CCKBW202GPO,
|
||||
BRCMS_SROM_CCKBW20UL2GPO,
|
||||
BRCMS_SROM_CCODE,
|
||||
BRCMS_SROM_CDDPO,
|
||||
BRCMS_SROM_DEVID,
|
||||
BRCMS_SROM_ET1MACADDR,
|
||||
BRCMS_SROM_EXTPAGAIN2G,
|
||||
BRCMS_SROM_EXTPAGAIN5G,
|
||||
BRCMS_SROM_FREQOFFSET_CORR,
|
||||
BRCMS_SROM_HW_IQCAL_EN,
|
||||
BRCMS_SROM_IL0MACADDR,
|
||||
BRCMS_SROM_IQCAL_SWP_DIS,
|
||||
BRCMS_SROM_LEDBH0,
|
||||
BRCMS_SROM_LEDBH1,
|
||||
BRCMS_SROM_LEDBH2,
|
||||
BRCMS_SROM_LEDBH3,
|
||||
BRCMS_SROM_LEDDC,
|
||||
BRCMS_SROM_LEGOFDM40DUPPO,
|
||||
BRCMS_SROM_LEGOFDMBW202GPO,
|
||||
BRCMS_SROM_LEGOFDMBW205GHPO,
|
||||
BRCMS_SROM_LEGOFDMBW205GLPO,
|
||||
BRCMS_SROM_LEGOFDMBW205GMPO,
|
||||
BRCMS_SROM_LEGOFDMBW20UL2GPO,
|
||||
BRCMS_SROM_LEGOFDMBW20UL5GHPO,
|
||||
BRCMS_SROM_LEGOFDMBW20UL5GLPO,
|
||||
BRCMS_SROM_LEGOFDMBW20UL5GMPO,
|
||||
BRCMS_SROM_MACADDR,
|
||||
BRCMS_SROM_MCS2GPO0,
|
||||
BRCMS_SROM_MCS2GPO1,
|
||||
BRCMS_SROM_MCS2GPO2,
|
||||
BRCMS_SROM_MCS2GPO3,
|
||||
BRCMS_SROM_MCS2GPO4,
|
||||
BRCMS_SROM_MCS2GPO5,
|
||||
BRCMS_SROM_MCS2GPO6,
|
||||
BRCMS_SROM_MCS2GPO7,
|
||||
BRCMS_SROM_MCS32PO,
|
||||
BRCMS_SROM_MCS5GHPO0,
|
||||
BRCMS_SROM_MCS5GHPO1,
|
||||
BRCMS_SROM_MCS5GHPO2,
|
||||
BRCMS_SROM_MCS5GHPO3,
|
||||
BRCMS_SROM_MCS5GHPO4,
|
||||
BRCMS_SROM_MCS5GHPO5,
|
||||
BRCMS_SROM_MCS5GHPO6,
|
||||
BRCMS_SROM_MCS5GHPO7,
|
||||
BRCMS_SROM_MCS5GLPO0,
|
||||
BRCMS_SROM_MCS5GLPO1,
|
||||
BRCMS_SROM_MCS5GLPO2,
|
||||
BRCMS_SROM_MCS5GLPO3,
|
||||
BRCMS_SROM_MCS5GLPO4,
|
||||
BRCMS_SROM_MCS5GLPO5,
|
||||
BRCMS_SROM_MCS5GLPO6,
|
||||
BRCMS_SROM_MCS5GLPO7,
|
||||
BRCMS_SROM_MCS5GPO0,
|
||||
BRCMS_SROM_MCS5GPO1,
|
||||
BRCMS_SROM_MCS5GPO2,
|
||||
BRCMS_SROM_MCS5GPO3,
|
||||
BRCMS_SROM_MCS5GPO4,
|
||||
BRCMS_SROM_MCS5GPO5,
|
||||
BRCMS_SROM_MCS5GPO6,
|
||||
BRCMS_SROM_MCS5GPO7,
|
||||
BRCMS_SROM_MCSBW202GPO,
|
||||
BRCMS_SROM_MCSBW205GHPO,
|
||||
BRCMS_SROM_MCSBW205GLPO,
|
||||
BRCMS_SROM_MCSBW205GMPO,
|
||||
BRCMS_SROM_MCSBW20UL2GPO,
|
||||
BRCMS_SROM_MCSBW20UL5GHPO,
|
||||
BRCMS_SROM_MCSBW20UL5GLPO,
|
||||
BRCMS_SROM_MCSBW20UL5GMPO,
|
||||
BRCMS_SROM_MCSBW402GPO,
|
||||
BRCMS_SROM_MCSBW405GHPO,
|
||||
BRCMS_SROM_MCSBW405GLPO,
|
||||
BRCMS_SROM_MCSBW405GMPO,
|
||||
BRCMS_SROM_MEASPOWER,
|
||||
BRCMS_SROM_OFDM2GPO,
|
||||
BRCMS_SROM_OFDM5GHPO,
|
||||
BRCMS_SROM_OFDM5GLPO,
|
||||
BRCMS_SROM_OFDM5GPO,
|
||||
BRCMS_SROM_OPO,
|
||||
BRCMS_SROM_PA0B0,
|
||||
BRCMS_SROM_PA0B1,
|
||||
BRCMS_SROM_PA0B2,
|
||||
BRCMS_SROM_PA0ITSSIT,
|
||||
BRCMS_SROM_PA0MAXPWR,
|
||||
BRCMS_SROM_PA1B0,
|
||||
BRCMS_SROM_PA1B1,
|
||||
BRCMS_SROM_PA1B2,
|
||||
BRCMS_SROM_PA1HIB0,
|
||||
BRCMS_SROM_PA1HIB1,
|
||||
BRCMS_SROM_PA1HIB2,
|
||||
BRCMS_SROM_PA1HIMAXPWR,
|
||||
BRCMS_SROM_PA1ITSSIT,
|
||||
BRCMS_SROM_PA1LOB0,
|
||||
BRCMS_SROM_PA1LOB1,
|
||||
BRCMS_SROM_PA1LOB2,
|
||||
BRCMS_SROM_PA1LOMAXPWR,
|
||||
BRCMS_SROM_PA1MAXPWR,
|
||||
BRCMS_SROM_PDETRANGE2G,
|
||||
BRCMS_SROM_PDETRANGE5G,
|
||||
BRCMS_SROM_PHYCAL_TEMPDELTA,
|
||||
BRCMS_SROM_RAWTEMPSENSE,
|
||||
BRCMS_SROM_REGREV,
|
||||
BRCMS_SROM_REV,
|
||||
BRCMS_SROM_RSSISAV2G,
|
||||
BRCMS_SROM_RSSISAV5G,
|
||||
BRCMS_SROM_RSSISMC2G,
|
||||
BRCMS_SROM_RSSISMC5G,
|
||||
BRCMS_SROM_RSSISMF2G,
|
||||
BRCMS_SROM_RSSISMF5G,
|
||||
BRCMS_SROM_RXCHAIN,
|
||||
BRCMS_SROM_RXPO2G,
|
||||
BRCMS_SROM_RXPO5G,
|
||||
BRCMS_SROM_STBCPO,
|
||||
BRCMS_SROM_TEMPCORRX,
|
||||
BRCMS_SROM_TEMPOFFSET,
|
||||
BRCMS_SROM_TEMPSENSE_OPTION,
|
||||
BRCMS_SROM_TEMPSENSE_SLOPE,
|
||||
BRCMS_SROM_TEMPTHRESH,
|
||||
BRCMS_SROM_TRI2G,
|
||||
BRCMS_SROM_TRI5GH,
|
||||
BRCMS_SROM_TRI5GL,
|
||||
BRCMS_SROM_TRI5G,
|
||||
BRCMS_SROM_TRISO2G,
|
||||
BRCMS_SROM_TRISO5G,
|
||||
BRCMS_SROM_TSSIPOS2G,
|
||||
BRCMS_SROM_TSSIPOS5G,
|
||||
BRCMS_SROM_TXCHAIN,
|
||||
BRCMS_SROM_TXPID2GA0,
|
||||
BRCMS_SROM_TXPID2GA1,
|
||||
BRCMS_SROM_TXPID2GA2,
|
||||
BRCMS_SROM_TXPID2GA3,
|
||||
BRCMS_SROM_TXPID5GA0,
|
||||
BRCMS_SROM_TXPID5GA1,
|
||||
BRCMS_SROM_TXPID5GA2,
|
||||
BRCMS_SROM_TXPID5GA3,
|
||||
BRCMS_SROM_TXPID5GHA0,
|
||||
BRCMS_SROM_TXPID5GHA1,
|
||||
BRCMS_SROM_TXPID5GHA2,
|
||||
BRCMS_SROM_TXPID5GHA3,
|
||||
BRCMS_SROM_TXPID5GLA0,
|
||||
BRCMS_SROM_TXPID5GLA1,
|
||||
BRCMS_SROM_TXPID5GLA2,
|
||||
BRCMS_SROM_TXPID5GLA3,
|
||||
/*
|
||||
* per-path identifiers (see srom.c)
|
||||
*/
|
||||
BRCMS_SROM_ITT2GA0,
|
||||
BRCMS_SROM_ITT2GA1,
|
||||
BRCMS_SROM_ITT2GA2,
|
||||
BRCMS_SROM_ITT2GA3,
|
||||
BRCMS_SROM_ITT5GA0,
|
||||
BRCMS_SROM_ITT5GA1,
|
||||
BRCMS_SROM_ITT5GA2,
|
||||
BRCMS_SROM_ITT5GA3,
|
||||
BRCMS_SROM_MAXP2GA0,
|
||||
BRCMS_SROM_MAXP2GA1,
|
||||
BRCMS_SROM_MAXP2GA2,
|
||||
BRCMS_SROM_MAXP2GA3,
|
||||
BRCMS_SROM_MAXP5GA0,
|
||||
BRCMS_SROM_MAXP5GA1,
|
||||
BRCMS_SROM_MAXP5GA2,
|
||||
BRCMS_SROM_MAXP5GA3,
|
||||
BRCMS_SROM_MAXP5GHA0,
|
||||
BRCMS_SROM_MAXP5GHA1,
|
||||
BRCMS_SROM_MAXP5GHA2,
|
||||
BRCMS_SROM_MAXP5GHA3,
|
||||
BRCMS_SROM_MAXP5GLA0,
|
||||
BRCMS_SROM_MAXP5GLA1,
|
||||
BRCMS_SROM_MAXP5GLA2,
|
||||
BRCMS_SROM_MAXP5GLA3,
|
||||
BRCMS_SROM_PA2GW0A0,
|
||||
BRCMS_SROM_PA2GW0A1,
|
||||
BRCMS_SROM_PA2GW0A2,
|
||||
BRCMS_SROM_PA2GW0A3,
|
||||
BRCMS_SROM_PA2GW1A0,
|
||||
BRCMS_SROM_PA2GW1A1,
|
||||
BRCMS_SROM_PA2GW1A2,
|
||||
BRCMS_SROM_PA2GW1A3,
|
||||
BRCMS_SROM_PA2GW2A0,
|
||||
BRCMS_SROM_PA2GW2A1,
|
||||
BRCMS_SROM_PA2GW2A2,
|
||||
BRCMS_SROM_PA2GW2A3,
|
||||
BRCMS_SROM_PA2GW3A0,
|
||||
BRCMS_SROM_PA2GW3A1,
|
||||
BRCMS_SROM_PA2GW3A2,
|
||||
BRCMS_SROM_PA2GW3A3,
|
||||
BRCMS_SROM_PA5GHW0A0,
|
||||
BRCMS_SROM_PA5GHW0A1,
|
||||
BRCMS_SROM_PA5GHW0A2,
|
||||
BRCMS_SROM_PA5GHW0A3,
|
||||
BRCMS_SROM_PA5GHW1A0,
|
||||
BRCMS_SROM_PA5GHW1A1,
|
||||
BRCMS_SROM_PA5GHW1A2,
|
||||
BRCMS_SROM_PA5GHW1A3,
|
||||
BRCMS_SROM_PA5GHW2A0,
|
||||
BRCMS_SROM_PA5GHW2A1,
|
||||
BRCMS_SROM_PA5GHW2A2,
|
||||
BRCMS_SROM_PA5GHW2A3,
|
||||
BRCMS_SROM_PA5GHW3A0,
|
||||
BRCMS_SROM_PA5GHW3A1,
|
||||
BRCMS_SROM_PA5GHW3A2,
|
||||
BRCMS_SROM_PA5GHW3A3,
|
||||
BRCMS_SROM_PA5GLW0A0,
|
||||
BRCMS_SROM_PA5GLW0A1,
|
||||
BRCMS_SROM_PA5GLW0A2,
|
||||
BRCMS_SROM_PA5GLW0A3,
|
||||
BRCMS_SROM_PA5GLW1A0,
|
||||
BRCMS_SROM_PA5GLW1A1,
|
||||
BRCMS_SROM_PA5GLW1A2,
|
||||
BRCMS_SROM_PA5GLW1A3,
|
||||
BRCMS_SROM_PA5GLW2A0,
|
||||
BRCMS_SROM_PA5GLW2A1,
|
||||
BRCMS_SROM_PA5GLW2A2,
|
||||
BRCMS_SROM_PA5GLW2A3,
|
||||
BRCMS_SROM_PA5GLW3A0,
|
||||
BRCMS_SROM_PA5GLW3A1,
|
||||
BRCMS_SROM_PA5GLW3A2,
|
||||
BRCMS_SROM_PA5GLW3A3,
|
||||
BRCMS_SROM_PA5GW0A0,
|
||||
BRCMS_SROM_PA5GW0A1,
|
||||
BRCMS_SROM_PA5GW0A2,
|
||||
BRCMS_SROM_PA5GW0A3,
|
||||
BRCMS_SROM_PA5GW1A0,
|
||||
BRCMS_SROM_PA5GW1A1,
|
||||
BRCMS_SROM_PA5GW1A2,
|
||||
BRCMS_SROM_PA5GW1A3,
|
||||
BRCMS_SROM_PA5GW2A0,
|
||||
BRCMS_SROM_PA5GW2A1,
|
||||
BRCMS_SROM_PA5GW2A2,
|
||||
BRCMS_SROM_PA5GW2A3,
|
||||
BRCMS_SROM_PA5GW3A0,
|
||||
BRCMS_SROM_PA5GW3A1,
|
||||
BRCMS_SROM_PA5GW3A2,
|
||||
BRCMS_SROM_PA5GW3A3,
|
||||
};
|
||||
|
||||
#define BRCMS_NUMRATES 16 /* max # of rates in a rateset */
|
||||
#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */
|
||||
|
||||
/* phy types */
|
||||
#define PHY_TYPE_A 0 /* Phy type A */
|
||||
#define PHY_TYPE_G 2 /* Phy type G */
|
||||
#define PHY_TYPE_N 4 /* Phy type N */
|
||||
#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */
|
||||
#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */
|
||||
#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */
|
||||
#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */
|
||||
#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */
|
||||
|
||||
/* bw */
|
||||
#define BRCMS_10_MHZ 10 /* 10Mhz nphy channel bandwidth */
|
||||
#define BRCMS_20_MHZ 20 /* 20Mhz nphy channel bandwidth */
|
||||
#define BRCMS_40_MHZ 40 /* 40Mhz nphy channel bandwidth */
|
||||
|
||||
#define BRCMS_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */
|
||||
#define BRCMS_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */
|
||||
#define BRCMS_RSSI_VERY_LOW -80 /* Very low quality cutoffs */
|
||||
#define BRCMS_RSSI_LOW -70 /* Low quality cutoffs */
|
||||
#define BRCMS_RSSI_GOOD -68 /* Good quality cutoffs */
|
||||
#define BRCMS_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */
|
||||
#define BRCMS_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */
|
||||
|
||||
/* a large TX Power as an init value to factor out of min() calculations,
|
||||
* keep low enough to fit in an s8, units are .25 dBm
|
||||
*/
|
||||
#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
|
||||
|
||||
/* rate related definitions */
|
||||
#define BRCMS_RATE_FLAG 0x80 /* Flag to indicate it is a basic rate */
|
||||
#define BRCMS_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */
|
||||
|
||||
/* legacy rx Antenna diversity for SISO rates */
|
||||
#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
|
||||
#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
|
||||
#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
|
||||
#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
|
||||
#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
|
||||
/* default antdiv setting */
|
||||
#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0
|
||||
|
||||
/* legacy rx Antenna diversity for SISO rates */
|
||||
/* Tx on antenna 0, "legacy term Main" */
|
||||
#define ANT_TX_FORCE_0 0
|
||||
/* Tx on antenna 1, "legacy term Aux" */
|
||||
#define ANT_TX_FORCE_1 1
|
||||
/* Tx on phy's last good Rx antenna */
|
||||
#define ANT_TX_LAST_RX 3
|
||||
/* driver's default tx antenna setting */
|
||||
#define ANT_TX_DEF 3
|
||||
|
||||
/* Tx Chain values */
|
||||
/* def bitmap of txchain */
|
||||
#define TXCHAIN_DEF 0x1
|
||||
/* default bitmap of tx chains for nphy */
|
||||
#define TXCHAIN_DEF_NPHY 0x3
|
||||
/* default bitmap of tx chains for nphy */
|
||||
#define TXCHAIN_DEF_HTPHY 0x7
|
||||
/* def bitmap of rxchain */
|
||||
#define RXCHAIN_DEF 0x1
|
||||
/* default bitmap of rx chains for nphy */
|
||||
#define RXCHAIN_DEF_NPHY 0x3
|
||||
/* default bitmap of rx chains for nphy */
|
||||
#define RXCHAIN_DEF_HTPHY 0x7
|
||||
/* no antenna switch */
|
||||
#define ANTSWITCH_NONE 0
|
||||
/* antenna switch on 4321CB2, 2of3 */
|
||||
#define ANTSWITCH_TYPE_1 1
|
||||
/* antenna switch on 4321MPCI, 2of3 */
|
||||
#define ANTSWITCH_TYPE_2 2
|
||||
/* antenna switch on 4322, 2of3 */
|
||||
#define ANTSWITCH_TYPE_3 3
|
||||
|
||||
#define RXBUFSZ PKTBUFSZ
|
||||
|
||||
#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */
|
||||
|
||||
struct brcm_rateset {
|
||||
/* # rates in this set */
|
||||
u32 count;
|
||||
/* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 rates[WL_NUMRATES];
|
||||
};
|
||||
|
||||
struct brcms_c_rateset {
|
||||
uint count; /* number of rates in rates[] */
|
||||
/* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 rates[BRCMS_NUMRATES];
|
||||
u8 htphy_membership; /* HT PHY Membership */
|
||||
u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */
|
||||
};
|
||||
|
||||
/* All the HT-specific default advertised capabilities (including AMPDU)
|
||||
* should be grouped here at one place
|
||||
*/
|
||||
#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */
|
||||
|
||||
/* wlc internal bss_info */
|
||||
struct brcms_bss_info {
|
||||
u8 BSSID[ETH_ALEN]; /* network BSSID */
|
||||
u16 flags; /* flags for internal attributes */
|
||||
u8 SSID_len; /* the length of SSID */
|
||||
u8 SSID[32]; /* SSID string */
|
||||
s16 RSSI; /* receive signal strength (in dBm) */
|
||||
s16 SNR; /* receive signal SNR in dB */
|
||||
u16 beacon_period; /* units are Kusec */
|
||||
u16 chanspec; /* Channel num, bw, ctrl_sb and band */
|
||||
struct brcms_c_rateset rateset; /* supported rates */
|
||||
};
|
||||
|
||||
#define MAC80211_PROMISC_BCNS (1 << 0)
|
||||
#define MAC80211_SCAN (1 << 1)
|
||||
|
||||
/*
|
||||
* Public portion of common driver state structure.
|
||||
* The wlc handle points at this.
|
||||
*/
|
||||
struct brcms_pub {
|
||||
struct brcms_c_info *wlc;
|
||||
struct ieee80211_hw *ieee_hw;
|
||||
struct scb_ampdu *global_ampdu;
|
||||
uint mac80211_state;
|
||||
uint unit; /* device instance number */
|
||||
uint corerev; /* core revision */
|
||||
struct si_pub *sih; /* SI handle (cookie for siutils calls) */
|
||||
bool up; /* interface up and running */
|
||||
bool hw_off; /* HW is off */
|
||||
bool hw_up; /* one time hw up/down */
|
||||
bool _piomode; /* true if pio mode */
|
||||
uint _nbands; /* # bands supported */
|
||||
uint now; /* # elapsed seconds */
|
||||
|
||||
bool promisc; /* promiscuous destination address */
|
||||
bool delayed_down; /* down delayed */
|
||||
bool associated; /* true:part of [I]BSS, false: not */
|
||||
/* (union of stas_associated, aps_associated) */
|
||||
bool _ampdu; /* ampdu enabled or not */
|
||||
u8 _n_enab; /* bitmap of 11N + HT support */
|
||||
|
||||
u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */
|
||||
|
||||
int bcmerror; /* last bcm error */
|
||||
|
||||
u32 radio_disabled; /* bit vector for radio disabled reasons */
|
||||
|
||||
u16 boardrev; /* version # of particular board */
|
||||
u8 sromrev; /* version # of the srom */
|
||||
char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */
|
||||
u32 boardflags; /* Board specific flags from srom */
|
||||
u32 boardflags2; /* More board flags if sromrev >= 4 */
|
||||
bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
|
||||
|
||||
struct wl_cnt *_cnt; /* low-level counters in driver */
|
||||
};
|
||||
|
||||
enum wlc_par_id {
|
||||
IOV_MPC = 1,
|
||||
IOV_RTSTHRESH,
|
||||
IOV_QTXPOWER,
|
||||
IOV_BCN_LI_BCN /* Beacon listen interval in # of beacons */
|
||||
};
|
||||
|
||||
/***********************************************
|
||||
* Feature-related macros to optimize out code *
|
||||
* *********************************************
|
||||
*/
|
||||
|
||||
#define ENAB_1x1 0x01
|
||||
#define ENAB_2x2 0x02
|
||||
#define ENAB_3x3 0x04
|
||||
#define ENAB_4x4 0x08
|
||||
#define SUPPORT_11N (ENAB_1x1|ENAB_2x2)
|
||||
#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3)
|
||||
|
||||
/* WL11N Support */
|
||||
#define AMPDU_AGG_HOST 1
|
||||
|
||||
/* pri is priority encoded in the packet. This maps the Packet priority to
|
||||
* enqueue precedence as defined in wlc_prec_map
|
||||
*/
|
||||
extern const u8 wlc_prio2prec_map[];
|
||||
#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
|
||||
|
||||
#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */
|
||||
|
||||
/* Mask to describe all precedence levels */
|
||||
#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
|
||||
|
||||
/*
|
||||
* This maps priority to one precedence higher - Used by PS-Poll response
|
||||
* packets to simulate enqueue-at-head operation, but still maintain the
|
||||
* order on the queue
|
||||
*/
|
||||
#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
|
||||
BRCMS_PREC_COUNT - 1)
|
||||
|
||||
/* Define a bitmap of precedences comprised by each AC */
|
||||
#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
|
||||
#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
|
||||
#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
|
||||
#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \
|
||||
NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
|
||||
|
||||
/* network protection config */
|
||||
#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
|
||||
#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
|
||||
#define BRCMS_PROT_G_USER 3 /* gmode specified by user */
|
||||
#define BRCMS_PROT_OVERLAP 4 /* overlap */
|
||||
#define BRCMS_PROT_N_USER 10 /* nmode specified by user */
|
||||
#define BRCMS_PROT_N_CFG 11 /* n protection */
|
||||
#define BRCMS_PROT_N_CFG_OVR 12 /* n protection override */
|
||||
#define BRCMS_PROT_N_NONGF 13 /* non-GF protection */
|
||||
#define BRCMS_PROT_N_NONGF_OVR 14 /* non-GF protection override */
|
||||
#define BRCMS_PROT_N_PAM_OVR 15 /* n preamble override */
|
||||
#define BRCMS_PROT_N_OBSS 16 /* non-HT OBSS present */
|
||||
|
||||
/*
|
||||
* 54g modes (basic bits may still be overridden)
|
||||
*
|
||||
* GMODE_LEGACY_B
|
||||
* Rateset: 1b, 2b, 5.5, 11
|
||||
* Preamble: Long
|
||||
* Shortslot: Off
|
||||
* GMODE_AUTO
|
||||
* Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
|
||||
* Extended Rateset: 6, 9, 12, 48
|
||||
* Preamble: Long
|
||||
* Shortslot: Auto
|
||||
* GMODE_ONLY
|
||||
* Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
|
||||
* Extended Rateset: 6b, 9, 12b, 48
|
||||
* Preamble: Short required
|
||||
* Shortslot: Auto
|
||||
* GMODE_B_DEFERRED
|
||||
* Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
|
||||
* Extended Rateset: 6, 9, 12, 48
|
||||
* Preamble: Long
|
||||
* Shortslot: On
|
||||
* GMODE_PERFORMANCE
|
||||
* Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
|
||||
* Preamble: Short required
|
||||
* Shortslot: On and required
|
||||
* GMODE_LRS
|
||||
* Rateset: 1b, 2b, 5.5b, 11b
|
||||
* Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
|
||||
* Preamble: Long
|
||||
* Shortslot: Auto
|
||||
*/
|
||||
#define GMODE_LEGACY_B 0
|
||||
#define GMODE_AUTO 1
|
||||
#define GMODE_ONLY 2
|
||||
#define GMODE_B_DEFERRED 3
|
||||
#define GMODE_PERFORMANCE 4
|
||||
#define GMODE_LRS 5
|
||||
#define GMODE_MAX 6
|
||||
|
||||
/* MCS values greater than this enable multiple streams */
|
||||
#define HIGHEST_SINGLE_STREAM_MCS 7
|
||||
|
||||
#define MAXBANDS 2 /* Maximum #of bands */
|
||||
|
||||
/* max number of antenna configurations */
|
||||
#define ANT_SELCFG_MAX 4
|
||||
|
||||
struct brcms_antselcfg {
|
||||
u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */
|
||||
u8 num_antcfg; /* number of available antenna configurations */
|
||||
};
|
||||
|
||||
/* common functions for every port */
|
||||
struct brcms_c_info *
|
||||
brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
|
||||
bool piomode, void __iomem *regsva, struct pci_dev *btparam,
|
||||
uint *perr);
|
||||
extern uint brcms_c_detach(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_up(struct brcms_c_info *wlc);
|
||||
extern uint brcms_c_down(struct brcms_c_info *wlc);
|
||||
|
||||
extern bool brcms_c_chipmatch(u16 vendor, u16 device);
|
||||
extern void brcms_c_init(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_reset(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_intrson(struct brcms_c_info *wlc);
|
||||
extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
|
||||
extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
|
||||
extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
|
||||
extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
|
||||
extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
|
||||
struct sk_buff *sdu,
|
||||
struct ieee80211_hw *hw);
|
||||
extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
|
||||
|
||||
/* helper functions */
|
||||
extern void brcms_c_statsupd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx,
|
||||
int val);
|
||||
extern int brcms_c_get_header_len(void);
|
||||
extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
|
||||
bool promisc);
|
||||
extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc,
|
||||
int match_reg_offset,
|
||||
const u8 *addr);
|
||||
extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
|
||||
const struct ieee80211_tx_queue_params *arg,
|
||||
bool suspend);
|
||||
extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc);
|
||||
|
||||
/* common functions for every port */
|
||||
extern void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val,
|
||||
int bands);
|
||||
extern void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
|
||||
struct brcms_c_rateset *rateset);
|
||||
extern void brcms_default_rateset(struct brcms_c_info *wlc,
|
||||
struct brcms_c_rateset *rs);
|
||||
|
||||
extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
|
||||
struct ieee80211_sta *sta, u16 tid);
|
||||
extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
|
||||
u8 ba_wsize, uint max_rx_ampdu_bytes);
|
||||
extern char *getvar(struct si_pub *sih, enum brcms_srom_id id);
|
||||
extern int getintvar(struct si_pub *sih, enum brcms_srom_id id);
|
||||
|
||||
/* wlc_phy.c helper functions */
|
||||
extern void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val);
|
||||
|
||||
extern int brcms_c_module_register(struct brcms_pub *pub,
|
||||
const char *name, struct brcms_info *hdl,
|
||||
int (*down_fn)(void *handle));
|
||||
extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
|
||||
struct brcms_info *hdl);
|
||||
extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_enable_mac(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
|
||||
extern void brcms_c_scan_start(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_get_curband(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
|
||||
bool drop);
|
||||
|
||||
int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
|
||||
int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
|
||||
void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
|
||||
struct brcm_rateset *currs);
|
||||
int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs);
|
||||
int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period);
|
||||
u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx);
|
||||
void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
|
||||
s8 sslot_override);
|
||||
void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval);
|
||||
int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
|
||||
int brcms_c_get_tx_power(struct brcms_c_info *wlc);
|
||||
void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc);
|
||||
|
||||
/* helper functions */
|
||||
extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
|
||||
extern bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc);
|
||||
|
||||
#endif /* _BRCM_PUB_H_ */
|
514
drivers/net/wireless/brcm80211/brcmsmac/rate.c
Normal file
514
drivers/net/wireless/brcm80211/brcmsmac/rate.c
Normal file
@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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 <brcmu_wifi.h>
|
||||
#include <brcmu_utils.h>
|
||||
|
||||
#include "d11.h"
|
||||
#include "pub.h"
|
||||
#include "rate.h"
|
||||
|
||||
/*
|
||||
* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate
|
||||
* value
|
||||
*/
|
||||
const u8 rate_info[BRCM_MAXRATE + 1] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
|
||||
/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
|
||||
/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
|
||||
/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||
/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
|
||||
};
|
||||
|
||||
/* rates are in units of Kbps */
|
||||
const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = {
|
||||
/* MCS 0: SS 1, MOD: BPSK, CR 1/2 */
|
||||
{6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 1: SS 1, MOD: QPSK, CR 1/2 */
|
||||
{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 2: SS 1, MOD: QPSK, CR 3/4 */
|
||||
{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */
|
||||
{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */
|
||||
{65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 8: SS 2, MOD: BPSK, CR 1/2 */
|
||||
{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 9: SS 2, MOD: QPSK, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 10: SS 2, MOD: QPSK, CR 3/4 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
|
||||
{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
|
||||
{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
|
||||
{130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 16: SS 3, MOD: BPSK, CR 1/2 */
|
||||
{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 17: SS 3, MOD: QPSK, CR 1/2 */
|
||||
{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 18: SS 3, MOD: QPSK, CR 3/4 */
|
||||
{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
|
||||
{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
|
||||
{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
|
||||
{175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
|
||||
{195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 24: SS 4, MOD: BPSK, CR 1/2 */
|
||||
{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
|
||||
BRCM_RATE_6M},
|
||||
/* MCS 25: SS 4, MOD: QPSK, CR 1/2 */
|
||||
{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
|
||||
BRCM_RATE_12M},
|
||||
/* MCS 26: SS 4, MOD: QPSK, CR 3/4 */
|
||||
{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
|
||||
BRCM_RATE_18M},
|
||||
/* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
|
||||
{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
|
||||
BRCM_RATE_24M},
|
||||
/* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
|
||||
{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
|
||||
BRCM_RATE_36M},
|
||||
/* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
|
||||
{208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
|
||||
BRCM_RATE_48M},
|
||||
/* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
|
||||
{234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
|
||||
{260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
|
||||
BRCM_RATE_54M},
|
||||
/* MCS 32: SS 1, MOD: BPSK, CR 1/2 */
|
||||
{0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M},
|
||||
};
|
||||
|
||||
/*
|
||||
* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
|
||||
* Number of spatial streams: always 1 other fields: refer to table 78 of
|
||||
* section 17.3.2.2 of the original .11a standard
|
||||
*/
|
||||
struct legacy_phycfg {
|
||||
u32 rate_ofdm; /* ofdm mac rate */
|
||||
/* phy ctl byte 3, code rate, modulation type, # of streams */
|
||||
u8 tx_phy_ctl3;
|
||||
};
|
||||
|
||||
/* Number of legacy_rate_cfg entries in the table */
|
||||
#define LEGACY_PHYCFG_TABLE_SIZE 12
|
||||
|
||||
/*
|
||||
* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate
|
||||
* Eventually MIMOPHY would also be converted to this format
|
||||
* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps
|
||||
*/
|
||||
static const struct
|
||||
legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
|
||||
{BRCM_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */
|
||||
{BRCM_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */
|
||||
{BRCM_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */
|
||||
{BRCM_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */
|
||||
/* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */
|
||||
{BRCM_RATE_6M, 0x00},
|
||||
/* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */
|
||||
{BRCM_RATE_9M, 0x02},
|
||||
/* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */
|
||||
{BRCM_RATE_12M, 0x08},
|
||||
/* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */
|
||||
{BRCM_RATE_18M, 0x0A},
|
||||
/* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_24M, 0x10},
|
||||
/* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_36M, 0x12},
|
||||
/* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_48M, 0x19},
|
||||
/* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
|
||||
{BRCM_RATE_54M, 0x1A},
|
||||
};
|
||||
|
||||
/* Hardware rates (also encodes default basic rates) */
|
||||
|
||||
const struct brcms_c_rateset cck_ofdm_mimo_rates = {
|
||||
12,
|
||||
/* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, */
|
||||
{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
/* 54 Mbps */
|
||||
0x6c},
|
||||
0x00,
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset ofdm_mimo_rates = {
|
||||
8,
|
||||
/* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
/* Default ratesets that include MCS32 for 40BW channels */
|
||||
static const struct brcms_c_rateset cck_ofdm_40bw_mimo_rates = {
|
||||
12,
|
||||
/* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48 */
|
||||
{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
/* 54 Mbps */
|
||||
0x6c},
|
||||
0x00,
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
static const struct brcms_c_rateset ofdm_40bw_mimo_rates = {
|
||||
8,
|
||||
/* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset cck_ofdm_rates = {
|
||||
12,
|
||||
/* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48,*/
|
||||
{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
|
||||
/*54 Mbps */
|
||||
0x6c},
|
||||
0x00,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset gphy_legacy_rates = {
|
||||
4,
|
||||
/* 1b, 2b, 5.5b, 11b Mbps */
|
||||
{ 0x82, 0x84, 0x8b, 0x96},
|
||||
0x00,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset ofdm_rates = {
|
||||
8,
|
||||
/* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
|
||||
{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
|
||||
0x00,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
const struct brcms_c_rateset cck_rates = {
|
||||
4,
|
||||
/* 1b, 2b, 5.5, 11 Mbps */
|
||||
{ 0x82, 0x84, 0x0b, 0x16},
|
||||
0x00,
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
/* check if rateset is valid.
|
||||
* if check_brate is true, rateset without a basic rate is considered NOT valid.
|
||||
*/
|
||||
static bool brcms_c_rateset_valid(struct brcms_c_rateset *rs, bool check_brate)
|
||||
{
|
||||
uint idx;
|
||||
|
||||
if (!rs->count)
|
||||
return false;
|
||||
|
||||
if (!check_brate)
|
||||
return true;
|
||||
|
||||
/* error if no basic rates */
|
||||
for (idx = 0; idx < rs->count; idx++) {
|
||||
if (rs->rates[idx] & BRCMS_RATE_FLAG)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams)
|
||||
{
|
||||
int i;
|
||||
for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
|
||||
rs->mcs[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* filter based on hardware rateset, and sort filtered rateset with basic
|
||||
* bit(s) preserved, and check if resulting rateset is valid.
|
||||
*/
|
||||
bool
|
||||
brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
|
||||
const struct brcms_c_rateset *hw_rs,
|
||||
bool check_brate, u8 txstreams)
|
||||
{
|
||||
u8 rateset[BRCM_MAXRATE + 1];
|
||||
u8 r;
|
||||
uint count;
|
||||
uint i;
|
||||
|
||||
memset(rateset, 0, sizeof(rateset));
|
||||
count = rs->count;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
/* mask off "basic rate" bit, BRCMS_RATE_FLAG */
|
||||
r = (int)rs->rates[i] & BRCMS_RATE_MASK;
|
||||
if ((r > BRCM_MAXRATE) || (rate_info[r] == 0))
|
||||
continue;
|
||||
rateset[r] = rs->rates[i]; /* preserve basic bit! */
|
||||
}
|
||||
|
||||
/* fill out the rates in order, looking at only supported rates */
|
||||
count = 0;
|
||||
for (i = 0; i < hw_rs->count; i++) {
|
||||
r = hw_rs->rates[i] & BRCMS_RATE_MASK;
|
||||
if (rateset[r])
|
||||
rs->rates[count++] = rateset[r];
|
||||
}
|
||||
|
||||
rs->count = count;
|
||||
|
||||
/* only set the mcs rate bit if the equivalent hw mcs bit is set */
|
||||
for (i = 0; i < MCSSET_LEN; i++)
|
||||
rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
|
||||
|
||||
if (brcms_c_rateset_valid(rs, check_brate))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* calculate the rate of a rx'd frame and return it as a ratespec */
|
||||
u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp)
|
||||
{
|
||||
int phy_type;
|
||||
u32 rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
|
||||
|
||||
phy_type =
|
||||
((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
|
||||
|
||||
if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
|
||||
(phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
|
||||
switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
|
||||
case PRXS0_CCK:
|
||||
rspec =
|
||||
cck_phy2mac_rate(
|
||||
((struct cck_phy_hdr *) plcp)->signal);
|
||||
break;
|
||||
case PRXS0_OFDM:
|
||||
rspec =
|
||||
ofdm_phy2mac_rate(
|
||||
((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
|
||||
break;
|
||||
case PRXS0_PREN:
|
||||
rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
|
||||
if (plcp[0] & MIMO_PLCP_40MHZ) {
|
||||
/* indicate rspec is for 40 MHz mode */
|
||||
rspec &= ~RSPEC_BW_MASK;
|
||||
rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
|
||||
}
|
||||
break;
|
||||
case PRXS0_STDN:
|
||||
/* fallthru */
|
||||
default:
|
||||
/* not supported, error condition */
|
||||
break;
|
||||
}
|
||||
if (plcp3_issgi(plcp[3]))
|
||||
rspec |= RSPEC_SHORT_GI;
|
||||
} else
|
||||
if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
|
||||
rspec = ofdm_phy2mac_rate(
|
||||
((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
|
||||
else
|
||||
rspec = cck_phy2mac_rate(
|
||||
((struct cck_phy_hdr *) plcp)->signal);
|
||||
|
||||
return rspec;
|
||||
}
|
||||
|
||||
/* copy rateset src to dst as-is (no masking or sorting) */
|
||||
void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
|
||||
struct brcms_c_rateset *dst)
|
||||
{
|
||||
memcpy(dst, src, sizeof(struct brcms_c_rateset));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy and selectively filter one rateset to another.
|
||||
* 'basic_only' means only copy basic rates.
|
||||
* 'rates' indicates cck (11b) and ofdm rates combinations.
|
||||
* - 0: cck and ofdm
|
||||
* - 1: cck only
|
||||
* - 2: ofdm only
|
||||
* 'xmask' is the copy mask (typically 0x7f or 0xff).
|
||||
*/
|
||||
void
|
||||
brcms_c_rateset_filter(struct brcms_c_rateset *src, struct brcms_c_rateset *dst,
|
||||
bool basic_only, u8 rates, uint xmask, bool mcsallow)
|
||||
{
|
||||
uint i;
|
||||
uint r;
|
||||
uint count;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < src->count; i++) {
|
||||
r = src->rates[i];
|
||||
if (basic_only && !(r & BRCMS_RATE_FLAG))
|
||||
continue;
|
||||
if (rates == BRCMS_RATES_CCK &&
|
||||
is_ofdm_rate((r & BRCMS_RATE_MASK)))
|
||||
continue;
|
||||
if (rates == BRCMS_RATES_OFDM &&
|
||||
is_cck_rate((r & BRCMS_RATE_MASK)))
|
||||
continue;
|
||||
dst->rates[count++] = r & xmask;
|
||||
}
|
||||
dst->count = count;
|
||||
dst->htphy_membership = src->htphy_membership;
|
||||
|
||||
if (mcsallow && rates != BRCMS_RATES_CCK)
|
||||
memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
|
||||
else
|
||||
brcms_c_rateset_mcs_clear(dst);
|
||||
}
|
||||
|
||||
/* select rateset for a given phy_type and bandtype and filter it, sort it
|
||||
* and fill rs_tgt with result
|
||||
*/
|
||||
void
|
||||
brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
|
||||
const struct brcms_c_rateset *rs_hw,
|
||||
uint phy_type, int bandtype, bool cck_only,
|
||||
uint rate_mask, bool mcsallow, u8 bw, u8 txstreams)
|
||||
{
|
||||
const struct brcms_c_rateset *rs_dflt;
|
||||
struct brcms_c_rateset rs_sel;
|
||||
if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
|
||||
(PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
|
||||
if (bandtype == BRCM_BAND_5G)
|
||||
rs_dflt = (bw == BRCMS_20_MHZ ?
|
||||
&ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
|
||||
else
|
||||
rs_dflt = (bw == BRCMS_20_MHZ ?
|
||||
&cck_ofdm_mimo_rates :
|
||||
&cck_ofdm_40bw_mimo_rates);
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
|
||||
rs_dflt = (bandtype == BRCM_BAND_5G) ?
|
||||
&ofdm_rates : &cck_ofdm_rates;
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
|
||||
rs_dflt = &ofdm_rates;
|
||||
} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
|
||||
rs_dflt = &cck_ofdm_rates;
|
||||
} else {
|
||||
/* should not happen, error condition */
|
||||
rs_dflt = &cck_rates; /* force cck */
|
||||
}
|
||||
|
||||
/* if hw rateset is not supplied, assign selected rateset to it */
|
||||
if (!rs_hw)
|
||||
rs_hw = rs_dflt;
|
||||
|
||||
brcms_c_rateset_copy(rs_dflt, &rs_sel);
|
||||
brcms_c_rateset_mcs_upd(&rs_sel, txstreams);
|
||||
brcms_c_rateset_filter(&rs_sel, rs_tgt, false,
|
||||
cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM,
|
||||
rate_mask, mcsallow);
|
||||
brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
|
||||
mcsallow ? txstreams : 1);
|
||||
}
|
||||
|
||||
s16 brcms_c_rate_legacy_phyctl(uint rate)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
|
||||
if (rate == legacy_phycfg_table[i].rate_ofdm)
|
||||
return legacy_phycfg_table[i].tx_phy_ctl3;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset)
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < MCSSET_LEN; i++)
|
||||
rateset->mcs[i] = 0;
|
||||
}
|
||||
|
||||
void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams)
|
||||
{
|
||||
memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
|
||||
brcms_c_rateset_mcs_upd(rateset, txstreams);
|
||||
}
|
||||
|
||||
/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
|
||||
void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw)
|
||||
{
|
||||
if (bw == BRCMS_40_MHZ)
|
||||
setbit(rateset->mcs, 32);
|
||||
else
|
||||
clrbit(rateset->mcs, 32);
|
||||
}
|
250
drivers/net/wireless/brcm80211/brcmsmac/rate.h
Normal file
250
drivers/net/wireless/brcm80211/brcmsmac/rate.h
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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_RATE_H_
|
||||
#define _BRCM_RATE_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "d11.h"
|
||||
|
||||
extern const u8 rate_info[];
|
||||
extern const struct brcms_c_rateset cck_ofdm_mimo_rates;
|
||||
extern const struct brcms_c_rateset ofdm_mimo_rates;
|
||||
extern const struct brcms_c_rateset cck_ofdm_rates;
|
||||
extern const struct brcms_c_rateset ofdm_rates;
|
||||
extern const struct brcms_c_rateset cck_rates;
|
||||
extern const struct brcms_c_rateset gphy_legacy_rates;
|
||||
extern const struct brcms_c_rateset rate_limit_1_2;
|
||||
|
||||
struct brcms_mcs_info {
|
||||
/* phy rate in kbps [20Mhz] */
|
||||
u32 phy_rate_20;
|
||||
/* phy rate in kbps [40Mhz] */
|
||||
u32 phy_rate_40;
|
||||
/* phy rate in kbps [20Mhz] with SGI */
|
||||
u32 phy_rate_20_sgi;
|
||||
/* phy rate in kbps [40Mhz] with SGI */
|
||||
u32 phy_rate_40_sgi;
|
||||
/* phy ctl byte 3, code rate, modulation type, # of streams */
|
||||
u8 tx_phy_ctl3;
|
||||
/* matching legacy ofdm rate in 500bkps */
|
||||
u8 leg_ofdm;
|
||||
};
|
||||
|
||||
#define BRCMS_MAXMCS 32 /* max valid mcs index */
|
||||
#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */
|
||||
extern const struct brcms_mcs_info mcs_table[];
|
||||
|
||||
#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */
|
||||
#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */
|
||||
|
||||
/* returns num tx streams - 1 */
|
||||
static inline u8 mcs_2_txstreams(u8 mcs)
|
||||
{
|
||||
return (mcs_table[mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT;
|
||||
}
|
||||
|
||||
static inline uint mcs_2_rate(u8 mcs, bool is40, bool sgi)
|
||||
{
|
||||
if (sgi) {
|
||||
if (is40)
|
||||
return mcs_table[mcs].phy_rate_40_sgi;
|
||||
return mcs_table[mcs].phy_rate_20_sgi;
|
||||
}
|
||||
if (is40)
|
||||
return mcs_table[mcs].phy_rate_40;
|
||||
|
||||
return mcs_table[mcs].phy_rate_20;
|
||||
}
|
||||
|
||||
/* Macro to use the rate_info table */
|
||||
#define BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
|
||||
|
||||
/*
|
||||
* rate spec : holds rate and mode specific information required to generate a
|
||||
* tx frame. Legacy CCK and OFDM information is held in the same manner as was
|
||||
* done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO
|
||||
* specific information
|
||||
*/
|
||||
|
||||
/* rate spec bit fields */
|
||||
|
||||
/* Either 500Kbps units or MIMO MCS idx */
|
||||
#define RSPEC_RATE_MASK 0x0000007F
|
||||
/* mimo MCS is stored in RSPEC_RATE_MASK */
|
||||
#define RSPEC_MIMORATE 0x08000000
|
||||
/* mimo bw mask */
|
||||
#define RSPEC_BW_MASK 0x00000700
|
||||
/* mimo bw shift */
|
||||
#define RSPEC_BW_SHIFT 8
|
||||
/* mimo Space/Time/Frequency mode mask */
|
||||
#define RSPEC_STF_MASK 0x00003800
|
||||
/* mimo Space/Time/Frequency mode shift */
|
||||
#define RSPEC_STF_SHIFT 11
|
||||
/* mimo coding type mask */
|
||||
#define RSPEC_CT_MASK 0x0000C000
|
||||
/* mimo coding type shift */
|
||||
#define RSPEC_CT_SHIFT 14
|
||||
/* mimo num STC streams per PLCP defn. */
|
||||
#define RSPEC_STC_MASK 0x00300000
|
||||
/* mimo num STC streams per PLCP defn. */
|
||||
#define RSPEC_STC_SHIFT 20
|
||||
/* mimo bit indicates adv coding in use */
|
||||
#define RSPEC_LDPC_CODING 0x00400000
|
||||
/* mimo bit indicates short GI in use */
|
||||
#define RSPEC_SHORT_GI 0x00800000
|
||||
/* bit indicates override both rate & mode */
|
||||
#define RSPEC_OVERRIDE 0x80000000
|
||||
/* bit indicates override rate only */
|
||||
#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000
|
||||
|
||||
static inline bool rspec_active(u32 rspec)
|
||||
{
|
||||
return rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE);
|
||||
}
|
||||
|
||||
static inline u8 rspec_phytxbyte2(u32 rspec)
|
||||
{
|
||||
return (rspec & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
static inline u32 rspec_get_bw(u32 rspec)
|
||||
{
|
||||
return (rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT;
|
||||
}
|
||||
|
||||
static inline bool rspec_issgi(u32 rspec)
|
||||
{
|
||||
return (rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI;
|
||||
}
|
||||
|
||||
static inline bool rspec_is40mhz(u32 rspec)
|
||||
{
|
||||
u32 bw = rspec_get_bw(rspec);
|
||||
|
||||
return bw == PHY_TXC1_BW_40MHZ || bw == PHY_TXC1_BW_40MHZ_DUP;
|
||||
}
|
||||
|
||||
static inline uint rspec2rate(u32 rspec)
|
||||
{
|
||||
if (rspec & RSPEC_MIMORATE)
|
||||
return mcs_2_rate(rspec & RSPEC_RATE_MASK, rspec_is40mhz(rspec),
|
||||
rspec_issgi(rspec));
|
||||
return rspec & RSPEC_RATE_MASK;
|
||||
}
|
||||
|
||||
static inline u8 rspec_mimoplcp3(u32 rspec)
|
||||
{
|
||||
return (rspec & 0xf00000) >> 16;
|
||||
}
|
||||
|
||||
static inline bool plcp3_issgi(u8 plcp)
|
||||
{
|
||||
return (plcp & (RSPEC_SHORT_GI >> 16)) != 0;
|
||||
}
|
||||
|
||||
static inline uint rspec_stc(u32 rspec)
|
||||
{
|
||||
return (rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT;
|
||||
}
|
||||
|
||||
static inline uint rspec_stf(u32 rspec)
|
||||
{
|
||||
return (rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT;
|
||||
}
|
||||
|
||||
static inline bool is_mcs_rate(u32 ratespec)
|
||||
{
|
||||
return (ratespec & RSPEC_MIMORATE) != 0;
|
||||
}
|
||||
|
||||
static inline bool is_ofdm_rate(u32 ratespec)
|
||||
{
|
||||
return !is_mcs_rate(ratespec) &&
|
||||
(rate_info[ratespec & RSPEC_RATE_MASK] & BRCMS_RATE_FLAG);
|
||||
}
|
||||
|
||||
static inline bool is_cck_rate(u32 ratespec)
|
||||
{
|
||||
u32 rate = (ratespec & BRCMS_RATE_MASK);
|
||||
|
||||
return !is_mcs_rate(ratespec) && (
|
||||
rate == BRCM_RATE_1M || rate == BRCM_RATE_2M ||
|
||||
rate == BRCM_RATE_5M5 || rate == BRCM_RATE_11M);
|
||||
}
|
||||
|
||||
static inline bool is_single_stream(u8 mcs)
|
||||
{
|
||||
return mcs <= HIGHEST_SINGLE_STREAM_MCS || mcs == 32;
|
||||
}
|
||||
|
||||
static inline u8 cck_rspec(u8 cck)
|
||||
{
|
||||
return cck & RSPEC_RATE_MASK;
|
||||
}
|
||||
|
||||
/* Convert encoded rate value in plcp header to numerical rates in 500 KHz
|
||||
* increments */
|
||||
extern const u8 ofdm_rate_lookup[];
|
||||
|
||||
static inline u8 ofdm_phy2mac_rate(u8 rlpt)
|
||||
{
|
||||
return ofdm_rate_lookup[rlpt & 0x7];
|
||||
}
|
||||
|
||||
static inline u8 cck_phy2mac_rate(u8 signal)
|
||||
{
|
||||
return signal/5;
|
||||
}
|
||||
|
||||
/* Rates specified in brcms_c_rateset_filter() */
|
||||
#define BRCMS_RATES_CCK_OFDM 0
|
||||
#define BRCMS_RATES_CCK 1
|
||||
#define BRCMS_RATES_OFDM 2
|
||||
|
||||
/* sanitize, and sort a rateset with the basic bit(s) preserved, validate
|
||||
* rateset */
|
||||
extern bool
|
||||
brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
|
||||
const struct brcms_c_rateset *hw_rs,
|
||||
bool check_brate, u8 txstreams);
|
||||
/* copy rateset src to dst as-is (no masking or sorting) */
|
||||
extern void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
|
||||
struct brcms_c_rateset *dst);
|
||||
|
||||
/* would be nice to have these documented ... */
|
||||
extern u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
|
||||
|
||||
extern void brcms_c_rateset_filter(struct brcms_c_rateset *src,
|
||||
struct brcms_c_rateset *dst, bool basic_only, u8 rates, uint xmask,
|
||||
bool mcsallow);
|
||||
|
||||
extern void
|
||||
brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
|
||||
const struct brcms_c_rateset *rs_hw, uint phy_type,
|
||||
int bandtype, bool cck_only, uint rate_mask,
|
||||
bool mcsallow, u8 bw, u8 txstreams);
|
||||
|
||||
extern s16 brcms_c_rate_legacy_phyctl(uint rate);
|
||||
|
||||
extern void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams);
|
||||
extern void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset);
|
||||
extern void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset,
|
||||
u8 txstreams);
|
||||
extern void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset,
|
||||
u8 bw);
|
||||
|
||||
#endif /* _BRCM_RATE_H_ */
|
82
drivers/net/wireless/brcm80211/brcmsmac/scb.h
Normal file
82
drivers/net/wireless/brcm80211/brcmsmac/scb.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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_SCB_H_
|
||||
#define _BRCM_SCB_H_
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include <defs.h>
|
||||
#include "types.h"
|
||||
|
||||
#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
|
||||
|
||||
#define AMPDU_MAX_SCB_TID NUMPRIO
|
||||
|
||||
/* scb flags */
|
||||
#define SCB_WMECAP 0x0040
|
||||
#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */
|
||||
#define SCB_IS40 0x80000 /* 40MHz capable */
|
||||
#define SCB_STBCCAP 0x40000000 /* STBC Capable */
|
||||
|
||||
#define SCB_MAGIC 0xbeefcafe
|
||||
|
||||
/* structure to store per-tid state for the ampdu initiator */
|
||||
struct scb_ampdu_tid_ini {
|
||||
u8 tx_in_transit; /* number of pending mpdus in transit in driver */
|
||||
u8 tid; /* initiator tid for easy lookup */
|
||||
/* tx retry count; indexed by seq modulo */
|
||||
u8 txretry[AMPDU_TX_BA_MAX_WSIZE];
|
||||
struct scb *scb; /* backptr for easy lookup */
|
||||
u8 ba_wsize; /* negotiated ba window size (in pdu) */
|
||||
};
|
||||
|
||||
struct scb_ampdu {
|
||||
struct scb *scb; /* back pointer for easy reference */
|
||||
u8 mpdu_density; /* mpdu density */
|
||||
u8 max_pdu; /* max pdus allowed in ampdu */
|
||||
u8 release; /* # of mpdus released at a time */
|
||||
u16 min_len; /* min mpdu len to support the density */
|
||||
u32 max_rx_ampdu_bytes; /* max ampdu rcv length; 8k, 16k, 32k, 64k */
|
||||
|
||||
/*
|
||||
* This could easily be a ini[] pointer and we keep this info in wl
|
||||
* itself instead of having mac80211 hold it for us. Also could be made
|
||||
* dynamic per tid instead of static.
|
||||
*/
|
||||
/* initiator info - per tid (NUMPRIO): */
|
||||
struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID];
|
||||
};
|
||||
|
||||
/* station control block - one per remote MAC address */
|
||||
struct scb {
|
||||
u32 magic;
|
||||
u32 flags; /* various bit flags as defined below */
|
||||
u32 flags2; /* various bit flags2 as defined below */
|
||||
u8 state; /* current state bitfield of auth/assoc process */
|
||||
u8 ea[ETH_ALEN]; /* station address */
|
||||
uint fragresid[NUMPRIO];/* #bytes unused in frag buffer per prio */
|
||||
|
||||
u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */
|
||||
/* seqctl of last received frame (for dups) for non-QoS data and
|
||||
* management */
|
||||
u16 seqctl_nonqos;
|
||||
u16 seqnum[NUMPRIO];/* WME: driver maintained sw seqnum per priority */
|
||||
|
||||
struct scb_ampdu scb_ampdu; /* AMPDU state including per tid info */
|
||||
};
|
||||
|
||||
#endif /* _BRCM_SCB_H_ */
|
1298
drivers/net/wireless/brcm80211/brcmsmac/srom.c
Normal file
1298
drivers/net/wireless/brcm80211/brcmsmac/srom.c
Normal file
File diff suppressed because it is too large
Load Diff
34
drivers/net/wireless/brcm80211/brcmsmac/srom.h
Normal file
34
drivers/net/wireless/brcm80211/brcmsmac/srom.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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_SROM_H_
|
||||
#define _BRCM_SROM_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* Prototypes */
|
||||
extern int srom_var_init(struct si_pub *sih, void __iomem *curmap);
|
||||
extern void srom_free_vars(struct si_pub *sih);
|
||||
|
||||
extern int srom_read(struct si_pub *sih, uint bus, void *curmap,
|
||||
uint byteoff, uint nbytes, u16 *buf, bool check_crc);
|
||||
|
||||
/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP
|
||||
* and extract from it into name=value pairs
|
||||
*/
|
||||
extern int srom_parsecis(u8 **pcis, uint ciscnt,
|
||||
char **vars, uint *count);
|
||||
#endif /* _BRCM_SROM_H_ */
|
438
drivers/net/wireless/brcm80211/brcmsmac/stf.c
Normal file
438
drivers/net/wireless/brcm80211/brcmsmac/stf.c
Normal file
@ -0,0 +1,438 @@
|
||||
/*
|
||||
* 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 <net/mac80211.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "d11.h"
|
||||
#include "rate.h"
|
||||
#include "phy/phy_hal.h"
|
||||
#include "channel.h"
|
||||
#include "main.h"
|
||||
#include "stf.h"
|
||||
|
||||
#define MIN_SPATIAL_EXPANSION 0
|
||||
#define MAX_SPATIAL_EXPANSION 1
|
||||
|
||||
#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
|
||||
|
||||
#define BRCMS_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8))
|
||||
|
||||
#define NSTS_1 1
|
||||
#define NSTS_2 2
|
||||
#define NSTS_3 3
|
||||
#define NSTS_4 4
|
||||
|
||||
static const u8 txcore_default[5] = {
|
||||
(0), /* bitmap of the core enabled */
|
||||
(0x01), /* For Nsts = 1, enable core 1 */
|
||||
(0x03), /* For Nsts = 2, enable core 1 & 2 */
|
||||
(0x07), /* For Nsts = 3, enable core 1, 2 & 3 */
|
||||
(0x0f) /* For Nsts = 4, enable all cores */
|
||||
};
|
||||
|
||||
static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val)
|
||||
{
|
||||
/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
|
||||
if (BRCMS_STF_SS_STBC_RX(wlc)) {
|
||||
if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
|
||||
return;
|
||||
}
|
||||
|
||||
if (wlc->pub->up) {
|
||||
brcms_c_update_beacon(wlc);
|
||||
brcms_c_update_probe_resp(wlc, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to
|
||||
* turn on/off txchain.
|
||||
*/
|
||||
void brcms_c_tempsense_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct brcms_phy_pub *pi = wlc->band->pi;
|
||||
uint active_chains, txchain;
|
||||
|
||||
/* Check if the chip is too hot. Disable one Tx chain, if it is */
|
||||
/* high 4 bits are for Rx chain, low 4 bits are for Tx chain */
|
||||
active_chains = wlc_phy_stf_chain_active_get(pi);
|
||||
txchain = active_chains & 0xf;
|
||||
|
||||
if (wlc->stf->txchain == wlc->stf->hw_txchain) {
|
||||
if (txchain && (txchain < wlc->stf->hw_txchain))
|
||||
/* turn off 1 tx chain */
|
||||
brcms_c_stf_txchain_set(wlc, txchain, true);
|
||||
} else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
|
||||
if (txchain == wlc->stf->hw_txchain)
|
||||
/* turn back on txchain */
|
||||
brcms_c_stf_txchain_set(wlc, txchain, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
|
||||
u16 chanspec)
|
||||
{
|
||||
struct tx_power power;
|
||||
u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
|
||||
|
||||
/* Clear previous settings */
|
||||
*ss_algo_channel = 0;
|
||||
|
||||
if (!wlc->pub->up) {
|
||||
*ss_algo_channel = (u16) -1;
|
||||
return;
|
||||
}
|
||||
|
||||
wlc_phy_txpower_get_current(wlc->band->pi, &power,
|
||||
CHSPEC_CHANNEL(chanspec));
|
||||
|
||||
siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
|
||||
cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
|
||||
stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
|
||||
WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
|
||||
|
||||
/* criteria to choose stf mode */
|
||||
|
||||
/*
|
||||
* the "+3dbm (12 0.25db units)" is to account for the fact that with
|
||||
* CDD, tx occurs on both chains
|
||||
*/
|
||||
if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
|
||||
else
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
|
||||
|
||||
/*
|
||||
* STBC is ORed into to algo channel as STBC requires per-packet SCB
|
||||
* capability check so cannot be default mode of operation. One of
|
||||
* SISO, CDD have to be set
|
||||
*/
|
||||
if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
|
||||
setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
|
||||
}
|
||||
|
||||
static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val)
|
||||
{
|
||||
if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON))
|
||||
return false;
|
||||
|
||||
if ((int_val == ON) && (wlc->stf->txstreams == 1))
|
||||
return false;
|
||||
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
|
||||
{
|
||||
if ((int_val != HT_CAP_RX_STBC_NO)
|
||||
&& (int_val != HT_CAP_RX_STBC_ONE_STREAM))
|
||||
return false;
|
||||
|
||||
if (BRCMS_STF_SS_STBC_RX(wlc)) {
|
||||
if ((int_val != HT_CAP_RX_STBC_NO)
|
||||
&& (wlc->stf->rxstreams == 1))
|
||||
return false;
|
||||
}
|
||||
|
||||
brcms_c_stf_stbc_rx_ht_update(wlc, int_val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
|
||||
u8 core_mask)
|
||||
{
|
||||
BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
|
||||
wlc->pub->unit, Nsts, core_mask);
|
||||
|
||||
if (hweight8(core_mask) > wlc->stf->txstreams)
|
||||
core_mask = 0;
|
||||
|
||||
if ((hweight8(core_mask) == wlc->stf->txstreams) &&
|
||||
((core_mask & ~wlc->stf->txchain)
|
||||
|| !(core_mask & wlc->stf->txchain)))
|
||||
core_mask = wlc->stf->txchain;
|
||||
|
||||
wlc->stf->txcore[Nsts] = core_mask;
|
||||
/* Nsts = 1..4, txcore index = 1..4 */
|
||||
if (Nsts == 1) {
|
||||
/* Needs to update beacon and ucode generated response
|
||||
* frames when 1 stream core map changed
|
||||
*/
|
||||
wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
|
||||
brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
|
||||
if (wlc->clk) {
|
||||
brcms_c_suspend_mac_and_wait(wlc);
|
||||
brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
|
||||
brcms_c_enable_mac(wlc);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
|
||||
{
|
||||
int i;
|
||||
u8 core_mask = 0;
|
||||
|
||||
BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
|
||||
|
||||
wlc->stf->spatial_policy = (s8) val;
|
||||
for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
|
||||
core_mask = (val == MAX_SPATIAL_EXPANSION) ?
|
||||
wlc->stf->txchain : txcore_default[i];
|
||||
brcms_c_stf_txcore_set(wlc, (u8) i, core_mask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Centralized txant update function. call it whenever wlc->stf->txant and/or
|
||||
* wlc->stf->txchain change.
|
||||
*
|
||||
* Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
|
||||
* achieve various tx/rx antenna selection schemes
|
||||
*
|
||||
* legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
|
||||
* means auto(last rx).
|
||||
* for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
|
||||
* means last rx and do tx-antenna selection for SISO transmissions
|
||||
* for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7
|
||||
* means last rx and do tx-antenna selection for SISO transmissions
|
||||
* for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7
|
||||
* means both cores active
|
||||
*/
|
||||
static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
s8 txant;
|
||||
|
||||
txant = (s8) wlc->stf->txant;
|
||||
if (BRCMS_PHY_11N_CAP(wlc->band)) {
|
||||
if (txant == ANT_TX_FORCE_0) {
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_0;
|
||||
} else if (txant == ANT_TX_FORCE_1) {
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_1;
|
||||
|
||||
if (BRCMS_ISNPHY(wlc->band) &&
|
||||
NREV_GE(wlc->band->phyrev, 3)
|
||||
&& NREV_LT(wlc->band->phyrev, 7))
|
||||
wlc->stf->phytxant = PHY_TXC_ANT_2;
|
||||
} else {
|
||||
if (BRCMS_ISLCNPHY(wlc->band) ||
|
||||
BRCMS_ISSSLPNPHY(wlc->band))
|
||||
wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
|
||||
else {
|
||||
/* catch out of sync wlc->stf->txcore */
|
||||
WARN_ON(wlc->stf->txchain <= 0);
|
||||
wlc->stf->phytxant =
|
||||
wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (txant == ANT_TX_FORCE_0)
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
|
||||
else if (txant == ANT_TX_FORCE_1)
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
|
||||
else
|
||||
wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
|
||||
}
|
||||
|
||||
brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
|
||||
}
|
||||
|
||||
int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
|
||||
{
|
||||
u8 txchain = (u8) int_val;
|
||||
u8 txstreams;
|
||||
uint i;
|
||||
|
||||
if (wlc->stf->txchain == txchain)
|
||||
return 0;
|
||||
|
||||
if ((txchain & ~wlc->stf->hw_txchain)
|
||||
|| !(txchain & wlc->stf->hw_txchain))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* if nrate override is configured to be non-SISO STF mode, reject
|
||||
* reducing txchain to 1
|
||||
*/
|
||||
txstreams = (u8) hweight8(txchain);
|
||||
if (txstreams > MAX_STREAMS_SUPPORTED)
|
||||
return -EINVAL;
|
||||
|
||||
wlc->stf->txchain = txchain;
|
||||
wlc->stf->txstreams = txstreams;
|
||||
brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
|
||||
wlc->stf->txant =
|
||||
(wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
|
||||
_brcms_c_stf_phy_txant_upd(wlc);
|
||||
|
||||
wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
|
||||
wlc->stf->rxchain);
|
||||
|
||||
for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
|
||||
brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* update wlc->stf->ss_opmode which represents the operational stf_ss mode
|
||||
* we're using
|
||||
*/
|
||||
int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
|
||||
{
|
||||
int ret_code = 0;
|
||||
u8 prev_stf_ss;
|
||||
u8 upd_stf_ss;
|
||||
|
||||
prev_stf_ss = wlc->stf->ss_opmode;
|
||||
|
||||
/*
|
||||
* NOTE: opmode can only be SISO or CDD as STBC is decided on a
|
||||
* per-packet basis
|
||||
*/
|
||||
if (BRCMS_STBC_CAP_PHY(wlc) &&
|
||||
wlc->stf->ss_algosel_auto
|
||||
&& (wlc->stf->ss_algo_channel != (u16) -1)) {
|
||||
upd_stf_ss = (wlc->stf->txstreams == 1 ||
|
||||
isset(&wlc->stf->ss_algo_channel,
|
||||
PHY_TXC1_MODE_SISO)) ?
|
||||
PHY_TXC1_MODE_SISO : PHY_TXC1_MODE_CDD;
|
||||
} else {
|
||||
if (wlc->band != band)
|
||||
return ret_code;
|
||||
upd_stf_ss = (wlc->stf->txstreams == 1) ?
|
||||
PHY_TXC1_MODE_SISO : band->band_stf_ss_mode;
|
||||
}
|
||||
if (prev_stf_ss != upd_stf_ss) {
|
||||
wlc->stf->ss_opmode = upd_stf_ss;
|
||||
brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
|
||||
}
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
int brcms_c_stf_attach(struct brcms_c_info *wlc)
|
||||
{
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
|
||||
|
||||
if (BRCMS_ISNPHY(wlc->band) &&
|
||||
(wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
|
||||
PHY_TXC1_MODE_CDD;
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
|
||||
brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
|
||||
|
||||
brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
|
||||
wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
|
||||
wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
|
||||
|
||||
if (BRCMS_STBC_CAP_PHY(wlc)) {
|
||||
wlc->stf->ss_algosel_auto = true;
|
||||
/* Init the default value */
|
||||
wlc->stf->ss_algo_channel = (u16) -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcms_c_stf_detach(struct brcms_c_info *wlc)
|
||||
{
|
||||
}
|
||||
|
||||
void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
|
||||
{
|
||||
_brcms_c_stf_phy_txant_upd(wlc);
|
||||
}
|
||||
|
||||
void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
|
||||
{
|
||||
/* get available rx/tx chains */
|
||||
wlc->stf->hw_txchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_TXCHAIN);
|
||||
wlc->stf->hw_rxchain = (u8) getintvar(wlc->hw->sih, BRCMS_SROM_RXCHAIN);
|
||||
|
||||
/* these parameter are intended to be used for all PHY types */
|
||||
if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
|
||||
if (BRCMS_ISNPHY(wlc->band))
|
||||
wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
|
||||
else
|
||||
wlc->stf->hw_txchain = TXCHAIN_DEF;
|
||||
}
|
||||
|
||||
wlc->stf->txchain = wlc->stf->hw_txchain;
|
||||
wlc->stf->txstreams = (u8) hweight8(wlc->stf->hw_txchain);
|
||||
|
||||
if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
|
||||
if (BRCMS_ISNPHY(wlc->band))
|
||||
wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
|
||||
else
|
||||
wlc->stf->hw_rxchain = RXCHAIN_DEF;
|
||||
}
|
||||
|
||||
wlc->stf->rxchain = wlc->stf->hw_rxchain;
|
||||
wlc->stf->rxstreams = (u8) hweight8(wlc->stf->hw_rxchain);
|
||||
|
||||
/* initialize the txcore table */
|
||||
memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
|
||||
|
||||
/* default spatial_policy */
|
||||
wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
|
||||
brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
|
||||
}
|
||||
|
||||
static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
|
||||
u32 rspec)
|
||||
{
|
||||
u16 phytxant = wlc->stf->phytxant;
|
||||
|
||||
if (rspec_stf(rspec) != PHY_TXC1_MODE_SISO)
|
||||
phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
else if (wlc->stf->txant == ANT_TX_DEF)
|
||||
phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
|
||||
phytxant &= PHY_TXC_ANT_MASK;
|
||||
return phytxant;
|
||||
}
|
||||
|
||||
u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec)
|
||||
{
|
||||
return _brcms_c_stf_phytxchain_sel(wlc, rspec);
|
||||
}
|
||||
|
||||
u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec)
|
||||
{
|
||||
u16 phytxant = wlc->stf->phytxant;
|
||||
u16 mask = PHY_TXC_ANT_MASK;
|
||||
|
||||
/* for non-siso rates or default setting, use the available chains */
|
||||
if (BRCMS_ISNPHY(wlc->band)) {
|
||||
phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec);
|
||||
mask = PHY_TXC_HTANT_MASK;
|
||||
}
|
||||
phytxant |= phytxant & mask;
|
||||
return phytxant;
|
||||
}
|
42
drivers/net/wireless/brcm80211/brcmsmac/stf.h
Normal file
42
drivers/net/wireless/brcm80211/brcmsmac/stf.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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_STF_H_
|
||||
#define _BRCM_STF_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern int brcms_c_stf_attach(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_stf_detach(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
|
||||
u16 *ss_algo_channel,
|
||||
u16 chanspec);
|
||||
extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc,
|
||||
struct brcms_band *band);
|
||||
extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val,
|
||||
bool force);
|
||||
extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
|
||||
extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc);
|
||||
extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
|
||||
u32 rspec);
|
||||
extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc,
|
||||
u32 rspec);
|
||||
|
||||
#endif /* _BRCM_STF_H_ */
|
352
drivers/net/wireless/brcm80211/brcmsmac/types.h
Normal file
352
drivers/net/wireless/brcm80211/brcmsmac/types.h
Normal file
@ -0,0 +1,352 @@
|
||||
/*
|
||||
* 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_TYPES_H_
|
||||
#define _BRCM_TYPES_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#define WL_CHAN_FREQ_RANGE_2G 0
|
||||
#define WL_CHAN_FREQ_RANGE_5GL 1
|
||||
#define WL_CHAN_FREQ_RANGE_5GM 2
|
||||
#define WL_CHAN_FREQ_RANGE_5GH 3
|
||||
|
||||
/* boardflags */
|
||||
|
||||
/* Board has gpio 9 controlling the PA */
|
||||
#define BFL_PACTRL 0x00000002
|
||||
/* Not ok to power down the chip pll and oscillator */
|
||||
#define BFL_NOPLLDOWN 0x00000020
|
||||
/* Board supports the Front End Module */
|
||||
#define BFL_FEM 0x00000800
|
||||
/* Board has an external LNA in 2.4GHz band */
|
||||
#define BFL_EXTLNA 0x00001000
|
||||
/* Board has no PA */
|
||||
#define BFL_NOPA 0x00010000
|
||||
/* Power topology uses BUCKBOOST */
|
||||
#define BFL_BUCKBOOST 0x00200000
|
||||
/* Board has FEM and switch to share antenna w/ BT */
|
||||
#define BFL_FEM_BT 0x00400000
|
||||
/* Power topology doesn't use CBUCK */
|
||||
#define BFL_NOCBUCK 0x00800000
|
||||
/* Power topology uses PALDO */
|
||||
#define BFL_PALDO 0x02000000
|
||||
/* Board has an external LNA in 5GHz band */
|
||||
#define BFL_EXTLNA_5GHz 0x10000000
|
||||
|
||||
/* boardflags2 */
|
||||
|
||||
/* Board has an external rxbb regulator */
|
||||
#define BFL2_RXBB_INT_REG_DIS 0x00000001
|
||||
/* Flag to implement alternative A-band PLL settings */
|
||||
#define BFL2_APLL_WAR 0x00000002
|
||||
/* Board permits enabling TX Power Control */
|
||||
#define BFL2_TXPWRCTRL_EN 0x00000004
|
||||
/* Board supports the 2X4 diversity switch */
|
||||
#define BFL2_2X4_DIV 0x00000008
|
||||
/* Board supports 5G band power gain */
|
||||
#define BFL2_5G_PWRGAIN 0x00000010
|
||||
/* Board overrides ASPM and Clkreq settings */
|
||||
#define BFL2_PCIEWAR_OVR 0x00000020
|
||||
#define BFL2_LEGACY 0x00000080
|
||||
/* 4321mcm93 board uses Skyworks FEM */
|
||||
#define BFL2_SKWRKFEM_BRD 0x00000100
|
||||
/* Board has a WAR for clock-harmonic spurs */
|
||||
#define BFL2_SPUR_WAR 0x00000200
|
||||
/* Flag to narrow G-band PLL loop b/w */
|
||||
#define BFL2_GPLL_WAR 0x00000400
|
||||
/* Tx CCK pkts on Ant 0 only */
|
||||
#define BFL2_SINGLEANT_CCK 0x00001000
|
||||
/* WAR to reduce and avoid clock-harmonic spurs in 2G */
|
||||
#define BFL2_2G_SPUR_WAR 0x00002000
|
||||
/* Flag to widen G-band PLL loop b/w */
|
||||
#define BFL2_GPLL_WAR2 0x00010000
|
||||
#define BFL2_IPALVLSHIFT_3P3 0x00020000
|
||||
/* Use internal envelope detector for TX IQCAL */
|
||||
#define BFL2_INTERNDET_TXIQCAL 0x00040000
|
||||
/* Keep the buffered Xtal output from radio "ON". Most drivers will turn it
|
||||
* off without this flag to save power. */
|
||||
#define BFL2_XTALBUFOUTEN 0x00080000
|
||||
|
||||
/*
|
||||
* board specific GPIO assignment, gpio 0-3 are also customer-configurable
|
||||
* led
|
||||
*/
|
||||
|
||||
/* bit 9 controls the PA on new 4306 boards */
|
||||
#define BOARD_GPIO_PACTRL 0x200
|
||||
#define BOARD_GPIO_12 0x1000
|
||||
#define BOARD_GPIO_13 0x2000
|
||||
|
||||
/* **** Core type/rev defaults **** */
|
||||
#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27
|
||||
* also need to update wlc.h MAXCOREREV
|
||||
*/
|
||||
|
||||
#define NCONF 0x000001ff /* Supported nphy revs:
|
||||
* 0 4321a0
|
||||
* 1 4321a1
|
||||
* 2 4321b0/b1/c0/c1
|
||||
* 3 4322a0
|
||||
* 4 4322a1
|
||||
* 5 4716a0
|
||||
* 6 43222a0, 43224a0
|
||||
* 7 43226a0
|
||||
* 8 5357a0, 43236a0
|
||||
*/
|
||||
|
||||
#define LCNCONF 0x00000007 /* Supported lcnphy revs:
|
||||
* 0 4313a0, 4336a0, 4330a0
|
||||
* 1
|
||||
* 2 4330a0
|
||||
*/
|
||||
|
||||
#define SSLPNCONF 0x0000000f /* Supported sslpnphy revs:
|
||||
* 0 4329a0/k0
|
||||
* 1 4329b0/4329C0
|
||||
* 2 4319a0
|
||||
* 3 5356a0
|
||||
*/
|
||||
|
||||
/********************************************************************
|
||||
* Phy/Core Configuration. Defines macros to to check core phy/rev *
|
||||
* compile-time configuration. Defines default core support. *
|
||||
* ******************************************************************
|
||||
*/
|
||||
|
||||
/* Basic macros to check a configuration bitmask */
|
||||
|
||||
#define CONF_HAS(config, val) ((config) & (1 << (val)))
|
||||
#define CONF_MSK(config, mask) ((config) & (mask))
|
||||
#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low)))
|
||||
#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
|
||||
|
||||
#define CONF_IS(config, val) ((config) == (1 << (val)))
|
||||
#define CONF_GE(config, val) ((config) & (0-(1 << (val))))
|
||||
#define CONF_GT(config, val) ((config) & (0-2*(1 << (val))))
|
||||
#define CONF_LT(config, val) ((config) & ((1 << (val))-1))
|
||||
#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1))
|
||||
|
||||
/* Wrappers for some of the above, specific to config constants */
|
||||
|
||||
#define NCONF_HAS(val) CONF_HAS(NCONF, val)
|
||||
#define NCONF_MSK(mask) CONF_MSK(NCONF, mask)
|
||||
#define NCONF_IS(val) CONF_IS(NCONF, val)
|
||||
#define NCONF_GE(val) CONF_GE(NCONF, val)
|
||||
#define NCONF_GT(val) CONF_GT(NCONF, val)
|
||||
#define NCONF_LT(val) CONF_LT(NCONF, val)
|
||||
#define NCONF_LE(val) CONF_LE(NCONF, val)
|
||||
|
||||
#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val)
|
||||
#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask)
|
||||
#define LCNCONF_IS(val) CONF_IS(LCNCONF, val)
|
||||
#define LCNCONF_GE(val) CONF_GE(LCNCONF, val)
|
||||
#define LCNCONF_GT(val) CONF_GT(LCNCONF, val)
|
||||
#define LCNCONF_LT(val) CONF_LT(LCNCONF, val)
|
||||
#define LCNCONF_LE(val) CONF_LE(LCNCONF, val)
|
||||
|
||||
#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
|
||||
#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
|
||||
#define D11CONF_IS(val) CONF_IS(D11CONF, val)
|
||||
#define D11CONF_GE(val) CONF_GE(D11CONF, val)
|
||||
#define D11CONF_GT(val) CONF_GT(D11CONF, val)
|
||||
#define D11CONF_LT(val) CONF_LT(D11CONF, val)
|
||||
#define D11CONF_LE(val) CONF_LE(D11CONF, val)
|
||||
|
||||
#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
|
||||
#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val)
|
||||
|
||||
#define NREV_IS(var, val) \
|
||||
(NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
|
||||
|
||||
#define NREV_GE(var, val) \
|
||||
(NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
|
||||
|
||||
#define NREV_GT(var, val) \
|
||||
(NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
|
||||
|
||||
#define NREV_LT(var, val) \
|
||||
(NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
|
||||
|
||||
#define NREV_LE(var, val) \
|
||||
(NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define LCNREV_IS(var, val) \
|
||||
(LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
|
||||
|
||||
#define LCNREV_GE(var, val) \
|
||||
(LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
|
||||
|
||||
#define LCNREV_GT(var, val) \
|
||||
(LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
|
||||
|
||||
#define LCNREV_LT(var, val) \
|
||||
(LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
|
||||
|
||||
#define LCNREV_LE(var, val) \
|
||||
(LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define D11REV_IS(var, val) \
|
||||
(D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
|
||||
|
||||
#define D11REV_GE(var, val) \
|
||||
(D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
|
||||
|
||||
#define D11REV_GT(var, val) \
|
||||
(D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
|
||||
|
||||
#define D11REV_LT(var, val) \
|
||||
(D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
|
||||
|
||||
#define D11REV_LE(var, val) \
|
||||
(D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
|
||||
|
||||
#define PHYTYPE_IS(var, val)\
|
||||
(PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
|
||||
|
||||
/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
|
||||
|
||||
#define _PHYCONF_N (1 << PHY_TYPE_N)
|
||||
#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
|
||||
#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
|
||||
|
||||
#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
|
||||
|
||||
/* Utility macro to identify 802.11n (HT) capable PHYs */
|
||||
#define PHYTYPE_11N_CAP(phytype) \
|
||||
(PHYTYPE_IS(phytype, PHY_TYPE_N) || \
|
||||
PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
|
||||
PHYTYPE_IS(phytype, PHY_TYPE_SSN))
|
||||
|
||||
/* Last but not least: shorter wlc-specific var checks */
|
||||
#define BRCMS_ISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
|
||||
#define BRCMS_ISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
|
||||
#define BRCMS_ISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
|
||||
|
||||
#define BRCMS_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype)
|
||||
|
||||
/**********************************************************************
|
||||
* ------------- End of Core phy/rev configuration. ----------------- *
|
||||
* ********************************************************************
|
||||
*/
|
||||
|
||||
#define BCMMSG(dev, fmt, args...) \
|
||||
do { \
|
||||
if (brcm_msg_level & LOG_TRACE_VAL) \
|
||||
wiphy_err(dev, "%s: " fmt, __func__, ##args); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Register access macros.
|
||||
*
|
||||
* These macro's take a pointer to the address to read as one of their
|
||||
* arguments. The macro itself deduces the size of the IO transaction (u8, u16
|
||||
* or u32). Advantage of this approach in combination with using a struct to
|
||||
* define the registers in a register block, is that access size and access
|
||||
* location are defined in only one spot. This reduces the risk of the
|
||||
* programmer trying to use an unsupported transaction size on a register.
|
||||
*
|
||||
*/
|
||||
|
||||
#define R_REG(r) \
|
||||
({ \
|
||||
__typeof(*(r)) __osl_v; \
|
||||
switch (sizeof(*(r))) { \
|
||||
case sizeof(u8): \
|
||||
__osl_v = readb((u8 __iomem *)(r)); \
|
||||
break; \
|
||||
case sizeof(u16): \
|
||||
__osl_v = readw((u16 __iomem *)(r)); \
|
||||
break; \
|
||||
case sizeof(u32): \
|
||||
__osl_v = readl((u32 __iomem *)(r)); \
|
||||
break; \
|
||||
} \
|
||||
__osl_v; \
|
||||
})
|
||||
|
||||
#define W_REG(r, v) do { \
|
||||
switch (sizeof(*(r))) { \
|
||||
case sizeof(u8): \
|
||||
writeb((u8)((v) & 0xFF), (u8 __iomem *)(r)); \
|
||||
break; \
|
||||
case sizeof(u16): \
|
||||
writew((u16)((v) & 0xFFFF), (u16 __iomem *)(r)); \
|
||||
break; \
|
||||
case sizeof(u32): \
|
||||
writel((u32)(v), (u32 __iomem *)(r)); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef CONFIG_BCM47XX
|
||||
/*
|
||||
* bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
|
||||
* transactions. As a fix, a read after write is performed on certain places
|
||||
* in the code. Older chips and the newer 5357 family don't require this fix.
|
||||
*/
|
||||
#define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); })
|
||||
#else
|
||||
#define W_REG_FLUSH(r, v) W_REG((r), (v))
|
||||
#endif /* CONFIG_BCM47XX */
|
||||
|
||||
#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
|
||||
#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
|
||||
|
||||
#define SET_REG(r, mask, val) \
|
||||
W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
|
||||
|
||||
/* multi-bool data type: set of bools, mbool is true if any is set */
|
||||
|
||||
/* set one bool */
|
||||
#define mboolset(mb, bit) ((mb) |= (bit))
|
||||
/* clear one bool */
|
||||
#define mboolclr(mb, bit) ((mb) &= ~(bit))
|
||||
/* true if one bool is set */
|
||||
#define mboolisset(mb, bit) (((mb) & (bit)) != 0)
|
||||
#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
|
||||
|
||||
#define CEIL(x, y) (((x) + ((y)-1)) / (y))
|
||||
|
||||
/* forward declarations */
|
||||
struct wiphy;
|
||||
struct ieee80211_sta;
|
||||
struct ieee80211_tx_queue_params;
|
||||
struct brcms_info;
|
||||
struct brcms_c_info;
|
||||
struct brcms_hardware;
|
||||
struct brcms_txq_info;
|
||||
struct brcms_band;
|
||||
struct dma_pub;
|
||||
struct si_pub;
|
||||
struct tx_status;
|
||||
struct d11rxhdr;
|
||||
struct txpwr_limits;
|
||||
|
||||
/* iovar structure */
|
||||
struct brcmu_iovar {
|
||||
const char *name; /* name for lookup and display */
|
||||
u16 varid; /* id for switch */
|
||||
u16 flags; /* driver-specific flag bits */
|
||||
u16 type; /* base type of argument */
|
||||
u16 minlen; /* min length for buffer vars */
|
||||
};
|
||||
|
||||
/* brcm_msg_level is a bit vector with defs in defs.h */
|
||||
extern u32 brcm_msg_level;
|
||||
|
||||
#endif /* _BRCM_TYPES_H_ */
|
109
drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
Normal file
109
drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 <defs.h>
|
||||
#include "types.h"
|
||||
#include <ucode_loader.h>
|
||||
|
||||
enum {
|
||||
D11UCODE_NAMETAG_START = 0,
|
||||
D11LCN0BSINITVALS24,
|
||||
D11LCN0INITVALS24,
|
||||
D11LCN1BSINITVALS24,
|
||||
D11LCN1INITVALS24,
|
||||
D11LCN2BSINITVALS24,
|
||||
D11LCN2INITVALS24,
|
||||
D11N0ABSINITVALS16,
|
||||
D11N0BSINITVALS16,
|
||||
D11N0INITVALS16,
|
||||
D11UCODE_OVERSIGHT16_MIMO,
|
||||
D11UCODE_OVERSIGHT16_MIMOSZ,
|
||||
D11UCODE_OVERSIGHT24_LCN,
|
||||
D11UCODE_OVERSIGHT24_LCNSZ,
|
||||
D11UCODE_OVERSIGHT_BOMMAJOR,
|
||||
D11UCODE_OVERSIGHT_BOMMINOR
|
||||
};
|
||||
|
||||
int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = brcms_check_firmwares(wl);
|
||||
|
||||
rc = rc < 0 ? rc :
|
||||
brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0bsinitvals24,
|
||||
D11LCN0BSINITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0initvals24,
|
||||
D11LCN0INITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1bsinitvals24,
|
||||
D11LCN1BSINITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1initvals24,
|
||||
D11LCN1INITVALS24);
|
||||
rc = rc < 0 ? rc :
|
||||
brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2bsinitvals24,
|
||||
D11LCN2BSINITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2initvals24,
|
||||
D11LCN2INITVALS24);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0absinitvals16,
|
||||
D11N0ABSINITVALS16);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0bsinitvals16,
|
||||
D11N0BSINITVALS16);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0initvals16,
|
||||
D11N0INITVALS16);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_16_mimo,
|
||||
D11UCODE_OVERSIGHT16_MIMO);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_16_mimosz,
|
||||
D11UCODE_OVERSIGHT16_MIMOSZ);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_24_lcn,
|
||||
D11UCODE_OVERSIGHT24_LCN);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_24_lcnsz,
|
||||
D11UCODE_OVERSIGHT24_LCNSZ);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bommajor,
|
||||
D11UCODE_OVERSIGHT_BOMMAJOR);
|
||||
rc = rc < 0 ?
|
||||
rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bomminor,
|
||||
D11UCODE_OVERSIGHT_BOMMINOR);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void brcms_ucode_data_free(struct brcms_ucode *ucode)
|
||||
{
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn0bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn0initvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn1bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn1initvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn2bsinitvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11lcn2initvals24);
|
||||
brcms_ucode_free_buf((void *)ucode->d11n0absinitvals16);
|
||||
brcms_ucode_free_buf((void *)ucode->d11n0bsinitvals16);
|
||||
brcms_ucode_free_buf((void *)ucode->d11n0initvals16);
|
||||
brcms_ucode_free_buf((void *)ucode->bcm43xx_16_mimo);
|
||||
brcms_ucode_free_buf((void *)ucode->bcm43xx_24_lcn);
|
||||
brcms_ucode_free_buf((void *)ucode->bcm43xx_bommajor);
|
||||
brcms_ucode_free_buf((void *)ucode->bcm43xx_bomminor);
|
||||
}
|
58
drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
Normal file
58
drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.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 _BRCM_UCODE_H_
|
||||
#define _BRCM_UCODE_H_
|
||||
|
||||
#include "types.h" /* forward structure declarations */
|
||||
|
||||
#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */
|
||||
#define MAX_FW_SIZE 150000
|
||||
|
||||
#define UCODE_LOADER_API_VER 0
|
||||
|
||||
struct d11init;
|
||||
|
||||
struct brcms_ucode {
|
||||
struct d11init *d11lcn0bsinitvals24;
|
||||
struct d11init *d11lcn0initvals24;
|
||||
struct d11init *d11lcn1bsinitvals24;
|
||||
struct d11init *d11lcn1initvals24;
|
||||
struct d11init *d11lcn2bsinitvals24;
|
||||
struct d11init *d11lcn2initvals24;
|
||||
struct d11init *d11n0absinitvals16;
|
||||
struct d11init *d11n0bsinitvals16;
|
||||
struct d11init *d11n0initvals16;
|
||||
__le32 *bcm43xx_16_mimo;
|
||||
size_t bcm43xx_16_mimosz;
|
||||
__le32 *bcm43xx_24_lcn;
|
||||
size_t bcm43xx_24_lcnsz;
|
||||
u32 *bcm43xx_bommajor;
|
||||
u32 *bcm43xx_bomminor;
|
||||
};
|
||||
|
||||
extern int
|
||||
brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode);
|
||||
|
||||
extern void brcms_ucode_data_free(struct brcms_ucode *ucode);
|
||||
|
||||
extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf,
|
||||
unsigned int idx);
|
||||
extern int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes,
|
||||
unsigned int idx);
|
||||
extern void brcms_ucode_free_buf(void *);
|
||||
extern int brcms_check_firmwares(struct brcms_info *wl);
|
||||
|
||||
#endif /* _BRCM_UCODE_H_ */
|
29
drivers/net/wireless/brcm80211/brcmutil/Makefile
Normal file
29
drivers/net/wireless/brcm80211/brcmutil/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
#
|
||||
# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
|
||||
#
|
||||
# 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.
|
||||
|
||||
ccflags-y := \
|
||||
-Idrivers/net/wireless/brcm80211/brcmutil \
|
||||
-Idrivers/net/wireless/brcm80211/include
|
||||
|
||||
BRCMUTIL_OFILES := \
|
||||
utils.o \
|
||||
wifi.o
|
||||
|
||||
MODULEPFX := brcmutil
|
||||
|
||||
obj-$(CONFIG_BRCMUTIL) += $(MODULEPFX).o
|
||||
$(MODULEPFX)-objs = $(BRCMUTIL_OFILES)
|
600
drivers/net/wireless/brcm80211/brcmutil/utils.c
Normal file
600
drivers/net/wireless/brcm80211/brcmutil/utils.c
Normal file
@ -0,0 +1,600 @@
|
||||
/*
|
||||
* 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/netdevice.h>
|
||||
#include <brcmu_utils.h>
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
|
||||
MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
struct sk_buff *brcmu_pkt_buf_get_skb(uint len)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = dev_alloc_skb(len);
|
||||
if (skb) {
|
||||
skb_put(skb, len);
|
||||
skb->priority = 0;
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pkt_buf_get_skb);
|
||||
|
||||
/* Free the driver packet. Free the tag if present */
|
||||
void brcmu_pkt_buf_free_skb(struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
int nest = 0;
|
||||
|
||||
/* perversion: we use skb->next to chain multi-skb packets */
|
||||
while (skb) {
|
||||
nskb = skb->next;
|
||||
skb->next = NULL;
|
||||
|
||||
if (skb->destructor)
|
||||
/* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
|
||||
* destructor exists
|
||||
*/
|
||||
dev_kfree_skb_any(skb);
|
||||
else
|
||||
/* can free immediately (even in_irq()) if destructor
|
||||
* does not exist
|
||||
*/
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
nest++;
|
||||
skb = nskb;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pkt_buf_free_skb);
|
||||
|
||||
|
||||
/* copy a buffer into a pkt buffer chain */
|
||||
uint brcmu_pktfrombuf(struct sk_buff *p, uint offset, int len,
|
||||
unsigned char *buf)
|
||||
{
|
||||
uint n, ret = 0;
|
||||
|
||||
/* skip 'offset' bytes */
|
||||
for (; p && offset; p = p->next) {
|
||||
if (offset < (uint) (p->len))
|
||||
break;
|
||||
offset -= p->len;
|
||||
}
|
||||
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
/* copy the data */
|
||||
for (; p && len; p = p->next) {
|
||||
n = min((uint) (p->len) - offset, (uint) len);
|
||||
memcpy(p->data + offset, buf, n);
|
||||
buf += n;
|
||||
len -= n;
|
||||
ret += n;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktfrombuf);
|
||||
|
||||
/* return total length of buffer chain */
|
||||
uint brcmu_pkttotlen(struct sk_buff *p)
|
||||
{
|
||||
uint total;
|
||||
|
||||
total = 0;
|
||||
for (; p; p = p->next)
|
||||
total += p->len;
|
||||
return total;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pkttotlen);
|
||||
|
||||
/*
|
||||
* osl multiple-precedence packet queue
|
||||
* hi_prec is always >= the number of the highest non-empty precedence
|
||||
*/
|
||||
struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
|
||||
struct sk_buff *p)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
|
||||
if (pktq_full(pq) || pktq_pfull(pq, prec))
|
||||
return NULL;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if (q->head)
|
||||
q->tail->prev = p;
|
||||
else
|
||||
q->head = p;
|
||||
|
||||
q->tail = p;
|
||||
q->len++;
|
||||
|
||||
pq->len++;
|
||||
|
||||
if (pq->hi_prec < prec)
|
||||
pq->hi_prec = (u8) prec;
|
||||
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_penq);
|
||||
|
||||
struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
|
||||
struct sk_buff *p)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
|
||||
if (pktq_full(pq) || pktq_pfull(pq, prec))
|
||||
return NULL;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
if (q->head == NULL)
|
||||
q->tail = p;
|
||||
|
||||
p->prev = q->head;
|
||||
q->head = p;
|
||||
q->len++;
|
||||
|
||||
pq->len++;
|
||||
|
||||
if (pq->hi_prec < prec)
|
||||
pq->hi_prec = (u8) prec;
|
||||
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_penq_head);
|
||||
|
||||
struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
struct sk_buff *p;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
p = q->head;
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
q->head = p->prev;
|
||||
if (q->head == NULL)
|
||||
q->tail = NULL;
|
||||
|
||||
q->len--;
|
||||
|
||||
pq->len--;
|
||||
|
||||
p->prev = NULL;
|
||||
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_pdeq);
|
||||
|
||||
struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
struct sk_buff *p, *prev;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
p = q->head;
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
for (prev = NULL; p != q->tail; p = p->prev)
|
||||
prev = p;
|
||||
|
||||
if (prev)
|
||||
prev->prev = NULL;
|
||||
else
|
||||
q->head = NULL;
|
||||
|
||||
q->tail = prev;
|
||||
q->len--;
|
||||
|
||||
pq->len--;
|
||||
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_pdeq_tail);
|
||||
|
||||
void
|
||||
brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir,
|
||||
bool (*fn)(struct sk_buff *, void *), void *arg)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
struct sk_buff *p, *prev = NULL;
|
||||
|
||||
q = &pq->q[prec];
|
||||
p = q->head;
|
||||
while (p) {
|
||||
if (fn == NULL || (*fn) (p, arg)) {
|
||||
bool head = (p == q->head);
|
||||
if (head)
|
||||
q->head = p->prev;
|
||||
else
|
||||
prev->prev = p->prev;
|
||||
p->prev = NULL;
|
||||
brcmu_pkt_buf_free_skb(p);
|
||||
q->len--;
|
||||
pq->len--;
|
||||
p = (head ? q->head : prev->prev);
|
||||
} else {
|
||||
prev = p;
|
||||
p = p->prev;
|
||||
}
|
||||
}
|
||||
|
||||
if (q->head == NULL)
|
||||
q->tail = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_pflush);
|
||||
|
||||
void brcmu_pktq_flush(struct pktq *pq, bool dir,
|
||||
bool (*fn)(struct sk_buff *, void *), void *arg)
|
||||
{
|
||||
int prec;
|
||||
for (prec = 0; prec < pq->num_prec; prec++)
|
||||
brcmu_pktq_pflush(pq, prec, dir, fn, arg);
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_flush);
|
||||
|
||||
void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len)
|
||||
{
|
||||
int prec;
|
||||
|
||||
/* pq is variable size; only zero out what's requested */
|
||||
memset(pq, 0,
|
||||
offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
|
||||
|
||||
pq->num_prec = (u16) num_prec;
|
||||
|
||||
pq->max = (u16) max_len;
|
||||
|
||||
for (prec = 0; prec < num_prec; prec++)
|
||||
pq->q[prec].max = pq->max;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_init);
|
||||
|
||||
struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out)
|
||||
{
|
||||
int prec;
|
||||
|
||||
if (pq->len == 0)
|
||||
return NULL;
|
||||
|
||||
for (prec = 0; prec < pq->hi_prec; prec++)
|
||||
if (pq->q[prec].head)
|
||||
break;
|
||||
|
||||
if (prec_out)
|
||||
*prec_out = prec;
|
||||
|
||||
return pq->q[prec].tail;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_peek_tail);
|
||||
|
||||
/* Return sum of lengths of a specific set of precedences */
|
||||
int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp)
|
||||
{
|
||||
int prec, len;
|
||||
|
||||
len = 0;
|
||||
|
||||
for (prec = 0; prec <= pq->hi_prec; prec++)
|
||||
if (prec_bmp & (1 << prec))
|
||||
len += pq->q[prec].len;
|
||||
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_mlen);
|
||||
|
||||
/* Priority dequeue from a specific set of precedences */
|
||||
struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
|
||||
int *prec_out)
|
||||
{
|
||||
struct pktq_prec *q;
|
||||
struct sk_buff *p;
|
||||
int prec;
|
||||
|
||||
if (pq->len == 0)
|
||||
return NULL;
|
||||
|
||||
while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
|
||||
pq->hi_prec--;
|
||||
|
||||
while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
|
||||
if (prec-- == 0)
|
||||
return NULL;
|
||||
|
||||
q = &pq->q[prec];
|
||||
|
||||
p = q->head;
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
q->head = p->prev;
|
||||
if (q->head == NULL)
|
||||
q->tail = NULL;
|
||||
|
||||
q->len--;
|
||||
|
||||
if (prec_out)
|
||||
*prec_out = prec;
|
||||
|
||||
pq->len--;
|
||||
|
||||
p->prev = NULL;
|
||||
|
||||
return p;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_pktq_mdeq);
|
||||
|
||||
#if defined(BCMDBG)
|
||||
/* pretty hex print a pkt buffer chain */
|
||||
void brcmu_prpkt(const char *msg, struct sk_buff *p0)
|
||||
{
|
||||
struct sk_buff *p;
|
||||
|
||||
if (msg && (msg[0] != '\0'))
|
||||
printk(KERN_DEBUG "%s:\n", msg);
|
||||
|
||||
for (p = p0; p; p = p->next)
|
||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_prpkt);
|
||||
#endif /* defined(BCMDBG) */
|
||||
|
||||
/*
|
||||
* Traverse a string of 1-byte tag/1-byte length/variable-length value
|
||||
* triples, returning a pointer to the substring whose first element
|
||||
* matches tag
|
||||
*/
|
||||
struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen, uint key)
|
||||
{
|
||||
struct brcmu_tlv *elt;
|
||||
int totlen;
|
||||
|
||||
elt = (struct brcmu_tlv *) buf;
|
||||
totlen = buflen;
|
||||
|
||||
/* find tagged parameter */
|
||||
while (totlen >= 2) {
|
||||
int len = elt->len;
|
||||
|
||||
/* validate remaining totlen */
|
||||
if ((elt->id == key) && (totlen >= (len + 2)))
|
||||
return elt;
|
||||
|
||||
elt = (struct brcmu_tlv *) ((u8 *) elt + (len + 2));
|
||||
totlen -= (len + 2);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_parse_tlvs);
|
||||
|
||||
|
||||
#if defined(BCMDBG)
|
||||
int
|
||||
brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags, char *buf,
|
||||
int len)
|
||||
{
|
||||
int i;
|
||||
char *p = buf;
|
||||
char hexstr[16];
|
||||
int slen = 0, nlen = 0;
|
||||
u32 bit;
|
||||
const char *name;
|
||||
|
||||
if (len < 2 || !buf)
|
||||
return 0;
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
for (i = 0; flags != 0; i++) {
|
||||
bit = bd[i].bit;
|
||||
name = bd[i].name;
|
||||
if (bit == 0 && flags != 0) {
|
||||
/* print any unnamed bits */
|
||||
snprintf(hexstr, 16, "0x%X", flags);
|
||||
name = hexstr;
|
||||
flags = 0; /* exit loop */
|
||||
} else if ((flags & bit) == 0)
|
||||
continue;
|
||||
flags &= ~bit;
|
||||
nlen = strlen(name);
|
||||
slen += nlen;
|
||||
/* count btwn flag space */
|
||||
if (flags != 0)
|
||||
slen += 1;
|
||||
/* need NULL char as well */
|
||||
if (len <= slen)
|
||||
break;
|
||||
/* copy NULL char but don't count it */
|
||||
strncpy(p, name, nlen + 1);
|
||||
p += nlen;
|
||||
/* copy btwn flag space and NULL char */
|
||||
if (flags != 0)
|
||||
p += snprintf(p, 2, " ");
|
||||
len -= slen;
|
||||
}
|
||||
|
||||
/* indicate the str was too short */
|
||||
if (flags != 0) {
|
||||
if (len < 2)
|
||||
p -= 2 - len; /* overwrite last char */
|
||||
p += snprintf(p, 2, ">");
|
||||
}
|
||||
|
||||
return (int)(p - buf);
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_format_flags);
|
||||
|
||||
/*
|
||||
* print bytes formatted as hex to a string. return the resulting
|
||||
* string length
|
||||
*/
|
||||
int brcmu_format_hex(char *str, const void *bytes, int len)
|
||||
{
|
||||
int i;
|
||||
char *p = str;
|
||||
const u8 *src = (const u8 *)bytes;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
p += snprintf(p, 3, "%02X", *src);
|
||||
src++;
|
||||
}
|
||||
return (int)(p - str);
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_format_hex);
|
||||
#endif /* defined(BCMDBG) */
|
||||
|
||||
char *brcmu_chipname(uint chipid, char *buf, uint len)
|
||||
{
|
||||
const char *fmt;
|
||||
|
||||
fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
|
||||
snprintf(buf, len, fmt, chipid);
|
||||
return buf;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_chipname);
|
||||
|
||||
uint brcmu_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
|
||||
{
|
||||
uint len;
|
||||
|
||||
len = strlen(name) + 1;
|
||||
|
||||
if ((len + datalen) > buflen)
|
||||
return 0;
|
||||
|
||||
strncpy(buf, name, buflen);
|
||||
|
||||
/* append data onto the end of the name string */
|
||||
memcpy(&buf[len], data, datalen);
|
||||
len += datalen;
|
||||
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_mkiovar);
|
||||
|
||||
/* Quarter dBm units to mW
|
||||
* Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
|
||||
* Table is offset so the last entry is largest mW value that fits in
|
||||
* a u16.
|
||||
*/
|
||||
|
||||
#define QDBM_OFFSET 153 /* Offset for first entry */
|
||||
#define QDBM_TABLE_LEN 40 /* Table size */
|
||||
|
||||
/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
|
||||
* Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
|
||||
*/
|
||||
#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
|
||||
|
||||
/* Largest mW value that will round down to the last table entry,
|
||||
* QDBM_OFFSET + QDBM_TABLE_LEN-1.
|
||||
* Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
|
||||
* mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
|
||||
*/
|
||||
#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
|
||||
|
||||
static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
|
||||
/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
|
||||
/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
|
||||
/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
|
||||
/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
|
||||
/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
|
||||
/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
|
||||
};
|
||||
|
||||
u16 brcmu_qdbm_to_mw(u8 qdbm)
|
||||
{
|
||||
uint factor = 1;
|
||||
int idx = qdbm - QDBM_OFFSET;
|
||||
|
||||
if (idx >= QDBM_TABLE_LEN)
|
||||
/* clamp to max u16 mW value */
|
||||
return 0xFFFF;
|
||||
|
||||
/* scale the qdBm index up to the range of the table 0-40
|
||||
* where an offset of 40 qdBm equals a factor of 10 mW.
|
||||
*/
|
||||
while (idx < 0) {
|
||||
idx += 40;
|
||||
factor *= 10;
|
||||
}
|
||||
|
||||
/* return the mW value scaled down to the correct factor of 10,
|
||||
* adding in factor/2 to get proper rounding.
|
||||
*/
|
||||
return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_qdbm_to_mw);
|
||||
|
||||
u8 brcmu_mw_to_qdbm(u16 mw)
|
||||
{
|
||||
u8 qdbm;
|
||||
int offset;
|
||||
uint mw_uint = mw;
|
||||
uint boundary;
|
||||
|
||||
/* handle boundary case */
|
||||
if (mw_uint <= 1)
|
||||
return 0;
|
||||
|
||||
offset = QDBM_OFFSET;
|
||||
|
||||
/* move mw into the range of the table */
|
||||
while (mw_uint < QDBM_TABLE_LOW_BOUND) {
|
||||
mw_uint *= 10;
|
||||
offset -= 40;
|
||||
}
|
||||
|
||||
for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
|
||||
boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
|
||||
nqdBm_to_mW_map[qdbm]) / 2;
|
||||
if (mw_uint < boundary)
|
||||
break;
|
||||
}
|
||||
|
||||
qdbm += (u8) offset;
|
||||
|
||||
return qdbm;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_mw_to_qdbm);
|
||||
|
||||
uint brcmu_bitcount(u8 *bitmap, uint length)
|
||||
{
|
||||
uint bitcount = 0, i;
|
||||
u8 tmp;
|
||||
for (i = 0; i < length; i++) {
|
||||
tmp = bitmap[i];
|
||||
while (tmp) {
|
||||
bitcount++;
|
||||
tmp &= (tmp - 1);
|
||||
}
|
||||
}
|
||||
return bitcount;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_bitcount);
|
136
drivers/net/wireless/brcm80211/brcmutil/wifi.c
Normal file
136
drivers/net/wireless/brcm80211/brcmutil/wifi.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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 <brcmu_wifi.h>
|
||||
|
||||
/*
|
||||
* Verify the chanspec is using a legal set of parameters, i.e. that the
|
||||
* chanspec specified a band, bw, ctl_sb and channel and that the
|
||||
* combination could be legal given any set of circumstances.
|
||||
* RETURNS: true is the chanspec is malformed, false if it looks good.
|
||||
*/
|
||||
bool brcmu_chspec_malformed(u16 chanspec)
|
||||
{
|
||||
/* must be 2G or 5G band */
|
||||
if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
|
||||
return true;
|
||||
/* must be 20 or 40 bandwidth */
|
||||
if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
|
||||
return true;
|
||||
|
||||
/* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
|
||||
if (CHSPEC_IS20(chanspec)) {
|
||||
if (!CHSPEC_SB_NONE(chanspec))
|
||||
return true;
|
||||
} else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_chspec_malformed);
|
||||
|
||||
/*
|
||||
* This function returns the channel number that control traffic is being sent
|
||||
* on, for legacy channels this is just the channel number, for 40MHZ channels
|
||||
* it is the upper or lower 20MHZ sideband depending on the chanspec selected.
|
||||
*/
|
||||
u8 brcmu_chspec_ctlchan(u16 chspec)
|
||||
{
|
||||
u8 ctl_chan;
|
||||
|
||||
/* Is there a sideband ? */
|
||||
if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
|
||||
return CHSPEC_CHANNEL(chspec);
|
||||
} else {
|
||||
/*
|
||||
* we only support 40MHZ with sidebands. chanspec channel holds
|
||||
* the centre frequency, use that and the side band information
|
||||
* to reconstruct the control channel number
|
||||
*/
|
||||
if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
|
||||
/*
|
||||
* control chan is the upper 20 MHZ SB of the
|
||||
* 40MHZ channel
|
||||
*/
|
||||
ctl_chan = upper_20_sb(CHSPEC_CHANNEL(chspec));
|
||||
else
|
||||
/*
|
||||
* control chan is the lower 20 MHZ SB of the
|
||||
* 40MHZ channel
|
||||
*/
|
||||
ctl_chan = lower_20_sb(CHSPEC_CHANNEL(chspec));
|
||||
}
|
||||
|
||||
return ctl_chan;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_chspec_ctlchan);
|
||||
|
||||
/*
|
||||
* Return the channel number for a given frequency and base frequency.
|
||||
* The returned channel number is relative to the given base frequency.
|
||||
* If the given base frequency is zero, a base frequency of 5 GHz is assumed for
|
||||
* frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
|
||||
*
|
||||
* Frequency is specified in MHz.
|
||||
* The base frequency is specified as (start_factor * 500 kHz).
|
||||
* Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
|
||||
* 2.4 GHz and 5 GHz bands.
|
||||
*
|
||||
* The returned channel will be in the range [1, 14] in the 2.4 GHz band
|
||||
* and [0, 200] otherwise.
|
||||
* -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
|
||||
* frequency is not a 2.4 GHz channel, or if the frequency is not and even
|
||||
* multiple of 5 MHz from the base frequency to the base plus 1 GHz.
|
||||
*
|
||||
* Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
|
||||
*/
|
||||
int brcmu_mhz2channel(uint freq, uint start_factor)
|
||||
{
|
||||
int ch = -1;
|
||||
uint base;
|
||||
int offset;
|
||||
|
||||
/* take the default channel start frequency */
|
||||
if (start_factor == 0) {
|
||||
if (freq >= 2400 && freq <= 2500)
|
||||
start_factor = WF_CHAN_FACTOR_2_4_G;
|
||||
else if (freq >= 5000 && freq <= 6000)
|
||||
start_factor = WF_CHAN_FACTOR_5_G;
|
||||
}
|
||||
|
||||
if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
|
||||
return 14;
|
||||
|
||||
base = start_factor / 2;
|
||||
|
||||
/* check that the frequency is in 1GHz range of the base */
|
||||
if ((freq < base) || (freq > base + 1000))
|
||||
return -1;
|
||||
|
||||
offset = freq - base;
|
||||
ch = offset / 5;
|
||||
|
||||
/* check that frequency is a 5MHz multiple from the base */
|
||||
if (offset != (ch * 5))
|
||||
return -1;
|
||||
|
||||
/* restricted channel range check for 2.4G */
|
||||
if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
|
||||
return -1;
|
||||
|
||||
return ch;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmu_mhz2channel);
|
59
drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
Normal file
59
drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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_HW_IDS_H_
|
||||
#define _BRCM_HW_IDS_H_
|
||||
|
||||
#define BCM4325_D11DUAL_ID 0x431b
|
||||
#define BCM4325_D11G_ID 0x431c
|
||||
#define BCM4325_D11A_ID 0x431d
|
||||
|
||||
#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */
|
||||
#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */
|
||||
#define BCM4329_D11NDUAL_ID 0x432e
|
||||
|
||||
#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */
|
||||
#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */
|
||||
#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */
|
||||
|
||||
#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
|
||||
#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */
|
||||
|
||||
#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
|
||||
|
||||
#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
|
||||
#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
|
||||
|
||||
#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
|
||||
|
||||
/* Chip IDs */
|
||||
#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */
|
||||
#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */
|
||||
|
||||
#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */
|
||||
#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */
|
||||
#define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */
|
||||
#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */
|
||||
#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */
|
||||
#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */
|
||||
#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */
|
||||
#define BCM4325_CHIP_ID 0x4325 /* 4325 chipcommon chipid */
|
||||
#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */
|
||||
#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */
|
||||
#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */
|
||||
#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */
|
||||
|
||||
#endif /* _BRCM_HW_IDS_H_ */
|
223
drivers/net/wireless/brcm80211/include/brcmu_utils.h
Normal file
223
drivers/net/wireless/brcm80211/include/brcmu_utils.h
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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 _BRCMU_UTILS_H_
|
||||
#define _BRCMU_UTILS_H_
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
/*
|
||||
* Spin at most 'us' microseconds while 'exp' is true.
|
||||
* Caller should explicitly test 'exp' when this completes
|
||||
* and take appropriate error action if 'exp' is still true.
|
||||
*/
|
||||
#define SPINWAIT(exp, us) { \
|
||||
uint countdown = (us) + 9; \
|
||||
while ((exp) && (countdown >= 10)) {\
|
||||
udelay(10); \
|
||||
countdown -= 10; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* osl multi-precedence packet queue */
|
||||
#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
|
||||
#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
|
||||
|
||||
#define BCME_STRLEN 64 /* Max string length for BCM errors */
|
||||
|
||||
/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
|
||||
#define PKTBUFSZ 2048
|
||||
|
||||
#ifndef setbit
|
||||
#ifndef NBBY /* the BSD family defines NBBY */
|
||||
#define NBBY 8 /* 8 bits per byte */
|
||||
#endif /* #ifndef NBBY */
|
||||
#define setbit(a, i) (((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
|
||||
#define clrbit(a, i) (((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
|
||||
#define isset(a, i) (((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
|
||||
#define isclr(a, i) ((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
|
||||
#endif /* setbit */
|
||||
|
||||
#define NBITS(type) (sizeof(type) * 8)
|
||||
#define NBITVAL(nbits) (1 << (nbits))
|
||||
#define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
|
||||
#define NBITMASK(nbits) MAXBITVAL(nbits)
|
||||
#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
|
||||
|
||||
/* crc defines */
|
||||
#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
|
||||
#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
|
||||
|
||||
/* 18-bytes of Ethernet address buffer length */
|
||||
#define ETHER_ADDR_STR_LEN 18
|
||||
|
||||
struct pktq_prec {
|
||||
struct sk_buff *head; /* first packet to dequeue */
|
||||
struct sk_buff *tail; /* last packet to dequeue */
|
||||
u16 len; /* number of queued packets */
|
||||
u16 max; /* maximum number of queued packets */
|
||||
};
|
||||
|
||||
/* multi-priority pkt queue */
|
||||
struct pktq {
|
||||
u16 num_prec; /* number of precedences in use */
|
||||
u16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
|
||||
u16 max; /* total max packets */
|
||||
u16 len; /* total number of packets */
|
||||
/*
|
||||
* q array must be last since # of elements can be either
|
||||
* PKTQ_MAX_PREC or 1
|
||||
*/
|
||||
struct pktq_prec q[PKTQ_MAX_PREC];
|
||||
};
|
||||
|
||||
/* operations on a specific precedence in packet queue */
|
||||
|
||||
static inline int pktq_plen(struct pktq *pq, int prec)
|
||||
{
|
||||
return pq->q[prec].len;
|
||||
}
|
||||
|
||||
static inline int pktq_pavail(struct pktq *pq, int prec)
|
||||
{
|
||||
return pq->q[prec].max - pq->q[prec].len;
|
||||
}
|
||||
|
||||
static inline bool pktq_pfull(struct pktq *pq, int prec)
|
||||
{
|
||||
return pq->q[prec].len >= pq->q[prec].max;
|
||||
}
|
||||
|
||||
static inline bool pktq_pempty(struct pktq *pq, int prec)
|
||||
{
|
||||
return pq->q[prec].len == 0;
|
||||
}
|
||||
|
||||
static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec)
|
||||
{
|
||||
return pq->q[prec].head;
|
||||
}
|
||||
|
||||
static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec)
|
||||
{
|
||||
return pq->q[prec].tail;
|
||||
}
|
||||
|
||||
extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
|
||||
struct sk_buff *p);
|
||||
extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
|
||||
struct sk_buff *p);
|
||||
extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
|
||||
extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
|
||||
|
||||
/* packet primitives */
|
||||
extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
|
||||
extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb);
|
||||
|
||||
/* Empty the queue at particular precedence level */
|
||||
/* callback function fn(pkt, arg) returns true if pkt belongs to if */
|
||||
extern void brcmu_pktq_pflush(struct pktq *pq, int prec,
|
||||
bool dir, bool (*fn)(struct sk_buff *, void *), void *arg);
|
||||
|
||||
/* operations on a set of precedences in packet queue */
|
||||
|
||||
extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp);
|
||||
extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
|
||||
int *prec_out);
|
||||
|
||||
/* operations on packet queue as a whole */
|
||||
|
||||
static inline int pktq_len(struct pktq *pq)
|
||||
{
|
||||
return (int)pq->len;
|
||||
}
|
||||
|
||||
static inline int pktq_max(struct pktq *pq)
|
||||
{
|
||||
return (int)pq->max;
|
||||
}
|
||||
|
||||
static inline int pktq_avail(struct pktq *pq)
|
||||
{
|
||||
return (int)(pq->max - pq->len);
|
||||
}
|
||||
|
||||
static inline bool pktq_full(struct pktq *pq)
|
||||
{
|
||||
return pq->len >= pq->max;
|
||||
}
|
||||
|
||||
static inline bool pktq_empty(struct pktq *pq)
|
||||
{
|
||||
return pq->len == 0;
|
||||
}
|
||||
|
||||
extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len);
|
||||
/* prec_out may be NULL if caller is not interested in return value */
|
||||
extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out);
|
||||
extern void brcmu_pktq_flush(struct pktq *pq, bool dir,
|
||||
bool (*fn)(struct sk_buff *, void *), void *arg);
|
||||
|
||||
/* externs */
|
||||
/* packet */
|
||||
extern uint brcmu_pktfrombuf(struct sk_buff *p,
|
||||
uint offset, int len, unsigned char *buf);
|
||||
extern uint brcmu_pkttotlen(struct sk_buff *p);
|
||||
|
||||
/* ip address */
|
||||
struct ipv4_addr;
|
||||
|
||||
#ifdef BCMDBG
|
||||
extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
|
||||
#else
|
||||
#define brcmu_prpkt(a, b)
|
||||
#endif /* BCMDBG */
|
||||
|
||||
/* brcmu_format_flags() bit description structure */
|
||||
struct brcmu_bit_desc {
|
||||
u32 bit;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/* tag_ID/length/value_buffer tuple */
|
||||
struct brcmu_tlv {
|
||||
u8 id;
|
||||
u8 len;
|
||||
u8 data[1];
|
||||
};
|
||||
|
||||
/* externs */
|
||||
/* format/print */
|
||||
#if defined(BCMDBG)
|
||||
extern int brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags,
|
||||
char *buf, int len);
|
||||
extern int brcmu_format_hex(char *str, const void *bytes, int len);
|
||||
#endif
|
||||
|
||||
extern char *brcmu_chipname(uint chipid, char *buf, uint len);
|
||||
|
||||
extern struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen,
|
||||
uint key);
|
||||
|
||||
/* power conversion */
|
||||
extern u16 brcmu_qdbm_to_mw(u8 qdbm);
|
||||
extern u8 brcmu_mw_to_qdbm(u16 mw);
|
||||
|
||||
extern uint brcmu_mkiovar(char *name, char *data, uint datalen,
|
||||
char *buf, uint len);
|
||||
extern uint brcmu_bitcount(u8 *bitmap, uint bytelength);
|
||||
|
||||
#endif /* _BRCMU_UTILS_H_ */
|
275
drivers/net/wireless/brcm80211/include/brcmu_wifi.h
Normal file
275
drivers/net/wireless/brcm80211/include/brcmu_wifi.h
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* 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 _BRCMU_WIFI_H_
|
||||
#define _BRCMU_WIFI_H_
|
||||
|
||||
#include <linux/if_ether.h> /* for ETH_ALEN */
|
||||
#include <linux/ieee80211.h> /* for WLAN_PMKID_LEN */
|
||||
|
||||
/*
|
||||
* A chanspec (u16) holds the channel number, band, bandwidth and control
|
||||
* sideband
|
||||
*/
|
||||
|
||||
/* channel defines */
|
||||
#define CH_UPPER_SB 0x01
|
||||
#define CH_LOWER_SB 0x02
|
||||
#define CH_EWA_VALID 0x04
|
||||
#define CH_20MHZ_APART 4
|
||||
#define CH_10MHZ_APART 2
|
||||
#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
|
||||
#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
|
||||
#define BRCM_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */
|
||||
|
||||
/* bandstate array indices */
|
||||
#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */
|
||||
#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */
|
||||
|
||||
/*
|
||||
* max # supported channels. The max channel no is 216, this is that + 1
|
||||
* rounded up to a multiple of NBBY (8). DO NOT MAKE it > 255: channels are
|
||||
* u8's all over
|
||||
*/
|
||||
#define MAXCHANNEL 224
|
||||
|
||||
#define WL_CHANSPEC_CHAN_MASK 0x00ff
|
||||
#define WL_CHANSPEC_CHAN_SHIFT 0
|
||||
|
||||
#define WL_CHANSPEC_CTL_SB_MASK 0x0300
|
||||
#define WL_CHANSPEC_CTL_SB_SHIFT 8
|
||||
#define WL_CHANSPEC_CTL_SB_LOWER 0x0100
|
||||
#define WL_CHANSPEC_CTL_SB_UPPER 0x0200
|
||||
#define WL_CHANSPEC_CTL_SB_NONE 0x0300
|
||||
|
||||
#define WL_CHANSPEC_BW_MASK 0x0C00
|
||||
#define WL_CHANSPEC_BW_SHIFT 10
|
||||
#define WL_CHANSPEC_BW_10 0x0400
|
||||
#define WL_CHANSPEC_BW_20 0x0800
|
||||
#define WL_CHANSPEC_BW_40 0x0C00
|
||||
|
||||
#define WL_CHANSPEC_BAND_MASK 0xf000
|
||||
#define WL_CHANSPEC_BAND_SHIFT 12
|
||||
#define WL_CHANSPEC_BAND_5G 0x1000
|
||||
#define WL_CHANSPEC_BAND_2G 0x2000
|
||||
#define INVCHANSPEC 255
|
||||
|
||||
/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
|
||||
#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
|
||||
#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
|
||||
#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
|
||||
|
||||
#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
|
||||
#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
|
||||
|
||||
#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
|
||||
#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
|
||||
|
||||
#define CHSPEC_IS10(chspec) \
|
||||
(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
|
||||
|
||||
#define CHSPEC_IS20(chspec) \
|
||||
(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
|
||||
|
||||
#ifndef CHSPEC_IS40
|
||||
#define CHSPEC_IS40(chspec) \
|
||||
(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
|
||||
#endif
|
||||
|
||||
#define CHSPEC_IS5G(chspec) \
|
||||
(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
|
||||
|
||||
#define CHSPEC_IS2G(chspec) \
|
||||
(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
|
||||
|
||||
#define CHSPEC_SB_NONE(chspec) \
|
||||
(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
|
||||
|
||||
#define CHSPEC_SB_UPPER(chspec) \
|
||||
(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
|
||||
|
||||
#define CHSPEC_SB_LOWER(chspec) \
|
||||
(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
|
||||
|
||||
#define CHSPEC_CTL_CHAN(chspec) \
|
||||
((CHSPEC_SB_LOWER(chspec)) ? \
|
||||
(lower_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
|
||||
(upper_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))))
|
||||
|
||||
#define CHSPEC2BAND(chspec) (CHSPEC_IS5G(chspec) ? BRCM_BAND_5G : BRCM_BAND_2G)
|
||||
|
||||
#define CHANSPEC_STR_LEN 8
|
||||
|
||||
static inline int lower_20_sb(int channel)
|
||||
{
|
||||
return channel > CH_10MHZ_APART ? (channel - CH_10MHZ_APART) : 0;
|
||||
}
|
||||
|
||||
static inline int upper_20_sb(int channel)
|
||||
{
|
||||
return (channel < (MAXCHANNEL - CH_10MHZ_APART)) ?
|
||||
channel + CH_10MHZ_APART : 0;
|
||||
}
|
||||
|
||||
static inline int chspec_bandunit(u16 chspec)
|
||||
{
|
||||
return CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX;
|
||||
}
|
||||
|
||||
static inline u16 ch20mhz_chspec(int channel)
|
||||
{
|
||||
u16 rc = channel <= CH_MAX_2G_CHANNEL ?
|
||||
WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G;
|
||||
|
||||
return (u16)((u16)channel | WL_CHANSPEC_BW_20 |
|
||||
WL_CHANSPEC_CTL_SB_NONE | rc);
|
||||
}
|
||||
|
||||
static inline int next_20mhz_chan(int channel)
|
||||
{
|
||||
return channel < (MAXCHANNEL - CH_20MHZ_APART) ?
|
||||
channel + CH_20MHZ_APART : 0;
|
||||
}
|
||||
|
||||
/* defined rate in 500kbps */
|
||||
#define BRCM_MAXRATE 108 /* in 500kbps units */
|
||||
#define BRCM_RATE_1M 2 /* in 500kbps units */
|
||||
#define BRCM_RATE_2M 4 /* in 500kbps units */
|
||||
#define BRCM_RATE_5M5 11 /* in 500kbps units */
|
||||
#define BRCM_RATE_11M 22 /* in 500kbps units */
|
||||
#define BRCM_RATE_6M 12 /* in 500kbps units */
|
||||
#define BRCM_RATE_9M 18 /* in 500kbps units */
|
||||
#define BRCM_RATE_12M 24 /* in 500kbps units */
|
||||
#define BRCM_RATE_18M 36 /* in 500kbps units */
|
||||
#define BRCM_RATE_24M 48 /* in 500kbps units */
|
||||
#define BRCM_RATE_36M 72 /* in 500kbps units */
|
||||
#define BRCM_RATE_48M 96 /* in 500kbps units */
|
||||
#define BRCM_RATE_54M 108 /* in 500kbps units */
|
||||
|
||||
#define BRCM_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */
|
||||
|
||||
#define MCSSET_LEN 16
|
||||
|
||||
static inline bool ac_bitmap_tst(u8 bitmap, int prec)
|
||||
{
|
||||
return (bitmap & (1 << (prec))) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the chanspec is using a legal set of parameters, i.e. that the
|
||||
* chanspec specified a band, bw, ctl_sb and channel and that the
|
||||
* combination could be legal given any set of circumstances.
|
||||
* RETURNS: true is the chanspec is malformed, false if it looks good.
|
||||
*/
|
||||
extern bool brcmu_chspec_malformed(u16 chanspec);
|
||||
|
||||
/*
|
||||
* This function returns the channel number that control traffic is being sent
|
||||
* on, for legacy channels this is just the channel number, for 40MHZ channels
|
||||
* it is the upper or lower 20MHZ sideband depending on the chanspec selected.
|
||||
*/
|
||||
extern u8 brcmu_chspec_ctlchan(u16 chspec);
|
||||
|
||||
/*
|
||||
* Return the channel number for a given frequency and base frequency.
|
||||
* The returned channel number is relative to the given base frequency.
|
||||
* If the given base frequency is zero, a base frequency of 5 GHz is assumed for
|
||||
* frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
|
||||
*
|
||||
* Frequency is specified in MHz.
|
||||
* The base frequency is specified as (start_factor * 500 kHz).
|
||||
* Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
|
||||
* 2.4 GHz and 5 GHz bands.
|
||||
*
|
||||
* The returned channel will be in the range [1, 14] in the 2.4 GHz band
|
||||
* and [0, 200] otherwise.
|
||||
* -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
|
||||
* frequency is not a 2.4 GHz channel, or if the frequency is not and even
|
||||
* multiple of 5 MHz from the base frequency to the base plus 1 GHz.
|
||||
*
|
||||
* Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
|
||||
*/
|
||||
extern int brcmu_mhz2channel(uint freq, uint start_factor);
|
||||
|
||||
/* Enumerate crypto algorithms */
|
||||
#define CRYPTO_ALGO_OFF 0
|
||||
#define CRYPTO_ALGO_WEP1 1
|
||||
#define CRYPTO_ALGO_TKIP 2
|
||||
#define CRYPTO_ALGO_WEP128 3
|
||||
#define CRYPTO_ALGO_AES_CCM 4
|
||||
#define CRYPTO_ALGO_AES_RESERVED1 5
|
||||
#define CRYPTO_ALGO_AES_RESERVED2 6
|
||||
#define CRYPTO_ALGO_NALG 7
|
||||
|
||||
/* wireless security bitvec */
|
||||
|
||||
#define WEP_ENABLED 0x0001
|
||||
#define TKIP_ENABLED 0x0002
|
||||
#define AES_ENABLED 0x0004
|
||||
#define WSEC_SWFLAG 0x0008
|
||||
/* to go into transition mode without setting wep */
|
||||
#define SES_OW_ENABLED 0x0040
|
||||
|
||||
/* WPA authentication mode bitvec */
|
||||
#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
|
||||
#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */
|
||||
#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */
|
||||
#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */
|
||||
#define WPA_AUTH_RESERVED1 0x0008
|
||||
#define WPA_AUTH_RESERVED2 0x0010
|
||||
|
||||
#define WPA2_AUTH_RESERVED1 0x0020
|
||||
#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */
|
||||
#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */
|
||||
#define WPA2_AUTH_RESERVED3 0x0200
|
||||
#define WPA2_AUTH_RESERVED4 0x0400
|
||||
#define WPA2_AUTH_RESERVED5 0x0800
|
||||
|
||||
/* pmkid */
|
||||
#define MAXPMKID 16
|
||||
|
||||
#define DOT11_DEFAULT_RTS_LEN 2347
|
||||
#define DOT11_DEFAULT_FRAG_LEN 2346
|
||||
|
||||
#define DOT11_ICV_AES_LEN 8
|
||||
#define DOT11_QOS_LEN 2
|
||||
#define DOT11_IV_MAX_LEN 8
|
||||
#define DOT11_A4_HDR_LEN 30
|
||||
|
||||
#define HT_CAP_RX_STBC_NO 0x0
|
||||
#define HT_CAP_RX_STBC_ONE_STREAM 0x1
|
||||
|
||||
struct pmkid {
|
||||
u8 BSSID[ETH_ALEN];
|
||||
u8 PMKID[WLAN_PMKID_LEN];
|
||||
};
|
||||
|
||||
struct pmkid_list {
|
||||
u32 npmkid;
|
||||
struct pmkid pmkid[1];
|
||||
};
|
||||
|
||||
struct pmkid_cand {
|
||||
u8 BSSID[ETH_ALEN];
|
||||
u8 preauth;
|
||||
};
|
||||
|
||||
struct pmkid_cand_list {
|
||||
u32 npmkid_cand;
|
||||
struct pmkid_cand pmkid_cand[1];
|
||||
};
|
||||
|
||||
#endif /* _BRCMU_WIFI_H_ */
|
284
drivers/net/wireless/brcm80211/include/chipcommon.h
Normal file
284
drivers/net/wireless/brcm80211/include/chipcommon.h
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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 _SBCHIPC_H
|
||||
#define _SBCHIPC_H
|
||||
|
||||
#include "defs.h" /* for PAD macro */
|
||||
|
||||
struct chipcregs {
|
||||
u32 chipid; /* 0x0 */
|
||||
u32 capabilities;
|
||||
u32 corecontrol; /* corerev >= 1 */
|
||||
u32 bist;
|
||||
|
||||
/* OTP */
|
||||
u32 otpstatus; /* 0x10, corerev >= 10 */
|
||||
u32 otpcontrol;
|
||||
u32 otpprog;
|
||||
u32 otplayout; /* corerev >= 23 */
|
||||
|
||||
/* Interrupt control */
|
||||
u32 intstatus; /* 0x20 */
|
||||
u32 intmask;
|
||||
|
||||
/* Chip specific regs */
|
||||
u32 chipcontrol; /* 0x28, rev >= 11 */
|
||||
u32 chipstatus; /* 0x2c, rev >= 11 */
|
||||
|
||||
/* Jtag Master */
|
||||
u32 jtagcmd; /* 0x30, rev >= 10 */
|
||||
u32 jtagir;
|
||||
u32 jtagdr;
|
||||
u32 jtagctrl;
|
||||
|
||||
/* serial flash interface registers */
|
||||
u32 flashcontrol; /* 0x40 */
|
||||
u32 flashaddress;
|
||||
u32 flashdata;
|
||||
u32 PAD[1];
|
||||
|
||||
/* Silicon backplane configuration broadcast control */
|
||||
u32 broadcastaddress; /* 0x50 */
|
||||
u32 broadcastdata;
|
||||
|
||||
/* gpio - cleared only by power-on-reset */
|
||||
u32 gpiopullup; /* 0x58, corerev >= 20 */
|
||||
u32 gpiopulldown; /* 0x5c, corerev >= 20 */
|
||||
u32 gpioin; /* 0x60 */
|
||||
u32 gpioout; /* 0x64 */
|
||||
u32 gpioouten; /* 0x68 */
|
||||
u32 gpiocontrol; /* 0x6C */
|
||||
u32 gpiointpolarity; /* 0x70 */
|
||||
u32 gpiointmask; /* 0x74 */
|
||||
|
||||
/* GPIO events corerev >= 11 */
|
||||
u32 gpioevent;
|
||||
u32 gpioeventintmask;
|
||||
|
||||
/* Watchdog timer */
|
||||
u32 watchdog; /* 0x80 */
|
||||
|
||||
/* GPIO events corerev >= 11 */
|
||||
u32 gpioeventintpolarity;
|
||||
|
||||
/* GPIO based LED powersave registers corerev >= 16 */
|
||||
u32 gpiotimerval; /* 0x88 */
|
||||
u32 gpiotimeroutmask;
|
||||
|
||||
/* clock control */
|
||||
u32 clockcontrol_n; /* 0x90 */
|
||||
u32 clockcontrol_sb; /* aka m0 */
|
||||
u32 clockcontrol_pci; /* aka m1 */
|
||||
u32 clockcontrol_m2; /* mii/uart/mipsref */
|
||||
u32 clockcontrol_m3; /* cpu */
|
||||
u32 clkdiv; /* corerev >= 3 */
|
||||
u32 gpiodebugsel; /* corerev >= 28 */
|
||||
u32 capabilities_ext; /* 0xac */
|
||||
|
||||
/* pll delay registers (corerev >= 4) */
|
||||
u32 pll_on_delay; /* 0xb0 */
|
||||
u32 fref_sel_delay;
|
||||
u32 slow_clk_ctl; /* 5 < corerev < 10 */
|
||||
u32 PAD;
|
||||
|
||||
/* Instaclock registers (corerev >= 10) */
|
||||
u32 system_clk_ctl; /* 0xc0 */
|
||||
u32 clkstatestretch;
|
||||
u32 PAD[2];
|
||||
|
||||
/* Indirect backplane access (corerev >= 22) */
|
||||
u32 bp_addrlow; /* 0xd0 */
|
||||
u32 bp_addrhigh;
|
||||
u32 bp_data;
|
||||
u32 PAD;
|
||||
u32 bp_indaccess;
|
||||
u32 PAD[3];
|
||||
|
||||
/* More clock dividers (corerev >= 32) */
|
||||
u32 clkdiv2;
|
||||
u32 PAD[2];
|
||||
|
||||
/* In AI chips, pointer to erom */
|
||||
u32 eromptr; /* 0xfc */
|
||||
|
||||
/* ExtBus control registers (corerev >= 3) */
|
||||
u32 pcmcia_config; /* 0x100 */
|
||||
u32 pcmcia_memwait;
|
||||
u32 pcmcia_attrwait;
|
||||
u32 pcmcia_iowait;
|
||||
u32 ide_config;
|
||||
u32 ide_memwait;
|
||||
u32 ide_attrwait;
|
||||
u32 ide_iowait;
|
||||
u32 prog_config;
|
||||
u32 prog_waitcount;
|
||||
u32 flash_config;
|
||||
u32 flash_waitcount;
|
||||
u32 SECI_config; /* 0x130 SECI configuration */
|
||||
u32 PAD[3];
|
||||
|
||||
/* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
|
||||
u32 eci_output; /* 0x140 */
|
||||
u32 eci_control;
|
||||
u32 eci_inputlo;
|
||||
u32 eci_inputmi;
|
||||
u32 eci_inputhi;
|
||||
u32 eci_inputintpolaritylo;
|
||||
u32 eci_inputintpolaritymi;
|
||||
u32 eci_inputintpolarityhi;
|
||||
u32 eci_intmasklo;
|
||||
u32 eci_intmaskmi;
|
||||
u32 eci_intmaskhi;
|
||||
u32 eci_eventlo;
|
||||
u32 eci_eventmi;
|
||||
u32 eci_eventhi;
|
||||
u32 eci_eventmasklo;
|
||||
u32 eci_eventmaskmi;
|
||||
u32 eci_eventmaskhi;
|
||||
u32 PAD[3];
|
||||
|
||||
/* SROM interface (corerev >= 32) */
|
||||
u32 sromcontrol; /* 0x190 */
|
||||
u32 sromaddress;
|
||||
u32 sromdata;
|
||||
u32 PAD[17];
|
||||
|
||||
/* Clock control and hardware workarounds (corerev >= 20) */
|
||||
u32 clk_ctl_st; /* 0x1e0 */
|
||||
u32 hw_war;
|
||||
u32 PAD[70];
|
||||
|
||||
/* UARTs */
|
||||
u8 uart0data; /* 0x300 */
|
||||
u8 uart0imr;
|
||||
u8 uart0fcr;
|
||||
u8 uart0lcr;
|
||||
u8 uart0mcr;
|
||||
u8 uart0lsr;
|
||||
u8 uart0msr;
|
||||
u8 uart0scratch;
|
||||
u8 PAD[248]; /* corerev >= 1 */
|
||||
|
||||
u8 uart1data; /* 0x400 */
|
||||
u8 uart1imr;
|
||||
u8 uart1fcr;
|
||||
u8 uart1lcr;
|
||||
u8 uart1mcr;
|
||||
u8 uart1lsr;
|
||||
u8 uart1msr;
|
||||
u8 uart1scratch;
|
||||
u32 PAD[126];
|
||||
|
||||
/* PMU registers (corerev >= 20) */
|
||||
u32 pmucontrol; /* 0x600 */
|
||||
u32 pmucapabilities;
|
||||
u32 pmustatus;
|
||||
u32 res_state;
|
||||
u32 res_pending;
|
||||
u32 pmutimer;
|
||||
u32 min_res_mask;
|
||||
u32 max_res_mask;
|
||||
u32 res_table_sel;
|
||||
u32 res_dep_mask;
|
||||
u32 res_updn_timer;
|
||||
u32 res_timer;
|
||||
u32 clkstretch;
|
||||
u32 pmuwatchdog;
|
||||
u32 gpiosel; /* 0x638, rev >= 1 */
|
||||
u32 gpioenable; /* 0x63c, rev >= 1 */
|
||||
u32 res_req_timer_sel;
|
||||
u32 res_req_timer;
|
||||
u32 res_req_mask;
|
||||
u32 PAD;
|
||||
u32 chipcontrol_addr; /* 0x650 */
|
||||
u32 chipcontrol_data; /* 0x654 */
|
||||
u32 regcontrol_addr;
|
||||
u32 regcontrol_data;
|
||||
u32 pllcontrol_addr;
|
||||
u32 pllcontrol_data;
|
||||
u32 pmustrapopt; /* 0x668, corerev >= 28 */
|
||||
u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */
|
||||
u32 PAD[100];
|
||||
u16 sromotp[768];
|
||||
};
|
||||
|
||||
/* chipid */
|
||||
#define CID_ID_MASK 0x0000ffff /* Chip Id mask */
|
||||
#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */
|
||||
#define CID_REV_SHIFT 16 /* Chip Revision shift */
|
||||
#define CID_PKG_MASK 0x00f00000 /* Package Option mask */
|
||||
#define CID_PKG_SHIFT 20 /* Package Option shift */
|
||||
#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */
|
||||
#define CID_CC_SHIFT 24
|
||||
#define CID_TYPE_MASK 0xf0000000 /* Chip Type */
|
||||
#define CID_TYPE_SHIFT 28
|
||||
|
||||
/* capabilities */
|
||||
#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */
|
||||
#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
|
||||
#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */
|
||||
/* UARTs are driven by internal divided clock */
|
||||
#define CC_CAP_UINTCLK 0x00000008
|
||||
#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */
|
||||
#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */
|
||||
#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */
|
||||
#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */
|
||||
#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */
|
||||
#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */
|
||||
#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */
|
||||
#define CC_CAP_PWR_CTL 0x00040000 /* Power control */
|
||||
#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
|
||||
#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
|
||||
#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */
|
||||
#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */
|
||||
#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */
|
||||
#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */
|
||||
#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */
|
||||
#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */
|
||||
/* Nand flash present, rev >= 35 */
|
||||
#define CC_CAP_NFLASH 0x80000000
|
||||
|
||||
#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */
|
||||
/* GSIO (spi/i2c) present, rev >= 37 */
|
||||
#define CC_CAP2_GSIO 0x00000002
|
||||
|
||||
/* pmucapabilities */
|
||||
#define PCAP_REV_MASK 0x000000ff
|
||||
#define PCAP_RC_MASK 0x00001f00
|
||||
#define PCAP_RC_SHIFT 8
|
||||
#define PCAP_TC_MASK 0x0001e000
|
||||
#define PCAP_TC_SHIFT 13
|
||||
#define PCAP_PC_MASK 0x001e0000
|
||||
#define PCAP_PC_SHIFT 17
|
||||
#define PCAP_VC_MASK 0x01e00000
|
||||
#define PCAP_VC_SHIFT 21
|
||||
#define PCAP_CC_MASK 0x1e000000
|
||||
#define PCAP_CC_SHIFT 25
|
||||
#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */
|
||||
#define PCAP5_PC_SHIFT 17
|
||||
#define PCAP5_VC_MASK 0x07c00000
|
||||
#define PCAP5_VC_SHIFT 22
|
||||
#define PCAP5_CC_MASK 0xf8000000
|
||||
#define PCAP5_CC_SHIFT 27
|
||||
|
||||
/*
|
||||
* Maximum delay for the PMU state transition in us.
|
||||
* This is an upper bound intended for spinwaits etc.
|
||||
*/
|
||||
#define PMU_MAX_TRANSITION_DLY 15000
|
||||
|
||||
#endif /* _SBCHIPC_H */
|
104
drivers/net/wireless/brcm80211/include/defs.h
Normal file
104
drivers/net/wireless/brcm80211/include/defs.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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_DEFS_H_
|
||||
#define _BRCM_DEFS_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define SI_BUS 0
|
||||
#define PCI_BUS 1
|
||||
#define PCMCIA_BUS 2
|
||||
#define SDIO_BUS 3
|
||||
#define JTAG_BUS 4
|
||||
#define USB_BUS 5
|
||||
#define SPI_BUS 6
|
||||
|
||||
#define OFF 0
|
||||
#define ON 1 /* ON = 1 */
|
||||
#define AUTO (-1) /* Auto = -1 */
|
||||
|
||||
/*
|
||||
* Priority definitions according 802.1D
|
||||
*/
|
||||
#define PRIO_8021D_NONE 2
|
||||
#define PRIO_8021D_BK 1
|
||||
#define PRIO_8021D_BE 0
|
||||
#define PRIO_8021D_EE 3
|
||||
#define PRIO_8021D_CL 4
|
||||
#define PRIO_8021D_VI 5
|
||||
#define PRIO_8021D_VO 6
|
||||
#define PRIO_8021D_NC 7
|
||||
|
||||
#define MAXPRIO 7
|
||||
#define NUMPRIO (MAXPRIO + 1)
|
||||
|
||||
#define WL_NUMRATES 16 /* max # of rates in a rateset */
|
||||
|
||||
#define BRCM_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */
|
||||
|
||||
#define BRCM_SET_CHANNEL 30
|
||||
#define BRCM_SET_SRL 32
|
||||
#define BRCM_SET_LRL 34
|
||||
#define BRCM_SET_BCNPRD 76
|
||||
|
||||
#define BRCM_GET_CURR_RATESET 114 /* current rateset */
|
||||
#define BRCM_GET_PHYLIST 180
|
||||
|
||||
/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
|
||||
|
||||
#define WL_RADIO_SW_DISABLE (1<<0)
|
||||
#define WL_RADIO_HW_DISABLE (1<<1)
|
||||
#define WL_RADIO_MPC_DISABLE (1<<2)
|
||||
/* some countries don't support any channel */
|
||||
#define WL_RADIO_COUNTRY_DISABLE (1<<3)
|
||||
|
||||
/* Override bit for SET_TXPWR. if set, ignore other level limits */
|
||||
#define WL_TXPWR_OVERRIDE (1U<<31)
|
||||
|
||||
/* band types */
|
||||
#define BRCM_BAND_AUTO 0 /* auto-select */
|
||||
#define BRCM_BAND_5G 1 /* 5 Ghz */
|
||||
#define BRCM_BAND_2G 2 /* 2.4 Ghz */
|
||||
#define BRCM_BAND_ALL 3 /* all bands */
|
||||
|
||||
/* Values for PM */
|
||||
#define PM_OFF 0
|
||||
#define PM_MAX 1
|
||||
|
||||
/* Message levels */
|
||||
#define LOG_ERROR_VAL 0x00000001
|
||||
#define LOG_TRACE_VAL 0x00000002
|
||||
|
||||
#define PM_OFF 0
|
||||
#define PM_MAX 1
|
||||
#define PM_FAST 2
|
||||
|
||||
/*
|
||||
* Sonics Configuration Space Registers.
|
||||
*/
|
||||
|
||||
/* core sbconfig regs are top 256bytes of regs */
|
||||
#define SBCONFIGOFF 0xf00
|
||||
|
||||
/* cpp contortions to concatenate w/arg prescan */
|
||||
#ifndef PAD
|
||||
#define _PADLINE(line) pad ## line
|
||||
#define _XSTR(line) _PADLINE(line)
|
||||
#define PAD _XSTR(__LINE__)
|
||||
#endif
|
||||
|
||||
#endif /* _BRCM_DEFS_H_ */
|
90
drivers/net/wireless/brcm80211/include/soc.h
Normal file
90
drivers/net/wireless/brcm80211/include/soc.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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_SOC_H
|
||||
#define _BRCM_SOC_H
|
||||
|
||||
#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
|
||||
|
||||
/* core codes */
|
||||
#define NODEV_CORE_ID 0x700 /* Invalid coreid */
|
||||
#define CC_CORE_ID 0x800 /* chipcommon core */
|
||||
#define ILINE20_CORE_ID 0x801 /* iline20 core */
|
||||
#define SRAM_CORE_ID 0x802 /* sram core */
|
||||
#define SDRAM_CORE_ID 0x803 /* sdram core */
|
||||
#define PCI_CORE_ID 0x804 /* pci core */
|
||||
#define MIPS_CORE_ID 0x805 /* mips core */
|
||||
#define ENET_CORE_ID 0x806 /* enet mac core */
|
||||
#define CODEC_CORE_ID 0x807 /* v90 codec core */
|
||||
#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
|
||||
#define ADSL_CORE_ID 0x809 /* ADSL core */
|
||||
#define ILINE100_CORE_ID 0x80a /* iline100 core */
|
||||
#define IPSEC_CORE_ID 0x80b /* ipsec core */
|
||||
#define UTOPIA_CORE_ID 0x80c /* utopia core */
|
||||
#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
|
||||
#define SOCRAM_CORE_ID 0x80e /* internal memory core */
|
||||
#define MEMC_CORE_ID 0x80f /* memc sdram core */
|
||||
#define OFDM_CORE_ID 0x810 /* OFDM phy core */
|
||||
#define EXTIF_CORE_ID 0x811 /* external interface core */
|
||||
#define D11_CORE_ID 0x812 /* 802.11 MAC core */
|
||||
#define APHY_CORE_ID 0x813 /* 802.11a phy core */
|
||||
#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
|
||||
#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
|
||||
#define MIPS33_CORE_ID 0x816 /* mips3302 core */
|
||||
#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
|
||||
#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
|
||||
#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
|
||||
#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
|
||||
#define SDIOH_CORE_ID 0x81b /* sdio host core */
|
||||
#define ROBO_CORE_ID 0x81c /* roboswitch core */
|
||||
#define ATA100_CORE_ID 0x81d /* parallel ATA core */
|
||||
#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
|
||||
#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
|
||||
#define PCIE_CORE_ID 0x820 /* pci express core */
|
||||
#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
|
||||
#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
|
||||
#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
|
||||
#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
|
||||
#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
|
||||
#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
|
||||
#define PMU_CORE_ID 0x827 /* PMU core */
|
||||
#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
|
||||
#define SDIOD_CORE_ID 0x829 /* SDIO device core */
|
||||
#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
|
||||
#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
|
||||
#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
|
||||
#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
|
||||
#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
|
||||
#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
|
||||
#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
|
||||
#define SC_CORE_ID 0x831 /* shared common core */
|
||||
#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
|
||||
#define SPIH_CORE_ID 0x833 /* SPI host core */
|
||||
#define I2S_CORE_ID 0x834 /* I2S core */
|
||||
#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
|
||||
#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
|
||||
#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
|
||||
/* Default component, in ai chips it maps all unused address ranges */
|
||||
#define DEF_AI_COMP 0xfff
|
||||
|
||||
/* Common core control flags */
|
||||
#define SICF_BIST_EN 0x8000
|
||||
#define SICF_PME_EN 0x4000
|
||||
#define SICF_CORE_BITS 0x3ffc
|
||||
#define SICF_FGC 0x0002
|
||||
#define SICF_CLOCK_EN 0x0001
|
||||
|
||||
#endif /* _BRCM_SOC_H */
|
@ -44,7 +44,7 @@ source "drivers/staging/wlan-ng/Kconfig"
|
||||
|
||||
source "drivers/staging/echo/Kconfig"
|
||||
|
||||
source "drivers/staging/brcm80211/Kconfig"
|
||||
|
||||
|
||||
source "drivers/staging/comedi/Kconfig"
|
||||
|
||||
|
@ -14,8 +14,8 @@ obj-$(CONFIG_USBIP_CORE) += usbip/
|
||||
obj-$(CONFIG_W35UND) += winbond/
|
||||
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
||||
obj-$(CONFIG_ECHO) += echo/
|
||||
obj-$(CONFIG_BRCMSMAC) += brcm80211/
|
||||
obj-$(CONFIG_BRCMFMAC) += brcm80211/
|
||||
|
||||
|
||||
obj-$(CONFIG_COMEDI) += comedi/
|
||||
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
|
||||
obj-$(CONFIG_ASUS_OLED) += asus_oled/
|
||||
|
Loading…
Reference in New Issue
Block a user