Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6

* 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (741 commits)
  staging:iio:meter:ade7753 should be 16 bit read not 8 bit for mode register.
  staging:iio:kfifo_buf fix double initialization of the ring device structure.
  staging:iio:accel:lis3l02dq: fix incorrect pointer passed to spi_set_drvdata.
  staging:iio:imu fix missing register table index for some channels
  spectra: enable device before poking it
  staging: rts_pstor: Fix a miswriting
  staging/lirc_bt829: Return -ENODEV when no hardware is found.
  staging/lirc_parallel: remove pointless prototypes.
  staging/lirc_parallel: fix panic on rmmod
  staging:iio:adc:ad7476: Incorrect pointer into spi_set_drvdata.
  Staging: zram: Fix kunmapping order
  Revert "gma500: Fix dependencies"
  gma500: Add medfield header
  gma500: wire up the mrst i2c bus from chip_info
  gma500: Fix DPU build
  gma500: Clean up the DPU config and make it runtime
  gma500: resync with Medfield progress
  gma500: Use the mrst helpers and power control for mode commit
  gma500@ Fix backlight range error
  gma500: More Moorestown muddle meddling means MM maybe might modeset
  ...

Fix up fairly trivial conflicts all over, mostly due to header file
cleanup conflicts, but some deleted files and some just context changes:
 - Documentation/feature-removal-schedule.txt
 - drivers/staging/bcm/headers.h
 - drivers/staging/brcm80211/brcmfmac/dhd_linux.c
 - drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
 - drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
 - drivers/staging/brcm80211/brcmfmac/wl_iw.c
 - drivers/staging/et131x/et131x_netdev.c
 - drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
 - drivers/staging/rtl8192e/r8192E.h
 - drivers/staging/usbip/userspace/src/utils.h
This commit is contained in:
Linus Torvalds 2011-07-25 23:26:34 -07:00
commit 1380516599
797 changed files with 49388 additions and 187765 deletions

View File

@ -193,20 +193,6 @@ Why: /proc/<pid>/oom_adj allows userspace to influence the oom killer's
---------------------------
What: CS5535/CS5536 obsolete GPIO driver
When: June 2011
Files: drivers/staging/cs5535_gpio/*
Check: drivers/staging/cs5535_gpio/cs5535_gpio.c
Why: A newer driver replaces this; it is drivers/gpio/cs5535-gpio.c, and
integrates with the Linux GPIO subsystem. The old driver has been
moved to staging, and will be removed altogether around 3.0.
Please test the new driver, and ensure that the functionality you
need and any bugfixes from the old driver are available in the new
one.
Who: Andres Salomon <dilinger@queued.net>
--------------------------
What: remove EXPORT_SYMBOL(kernel_thread)
When: August 2006
Files: arch/*/kernel/*_ksyms.c

View File

@ -1546,9 +1546,10 @@ F: drivers/net/tg3.*
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
M: Brett Rudley <brudley@broadcom.com>
M: Henry Ptasinski <henryp@broadcom.com>
M: Dowan Kim <dowan@broadcom.com>
M: Roland Vossen <rvossen@broadcom.com>
M: Arend van Spriel <arend@broadcom.com>
M: Franky (Zhenhui) Lin <frankyl@broadcom.com>
M: Kan Yan <kanyan@broadcom.com>
L: linux-wireless@vger.kernel.org
S: Supported
F: drivers/staging/brcm80211/
@ -6092,6 +6093,145 @@ L: devel@driverdev.osuosl.org
S: Maintained
F: drivers/staging/
STAGING - AGERE HERMES II and II.5 WIRELESS DRIVERS
M: Henk de Groot <pe1dnn@amsat.org>
S: Odd Fixes
F: drivers/staging/wlags49_h2/
F: drivers/staging/wlags49_h25/
STAGING - ASUS OLED
M: Jakub Schmidtke <sjakub@gmail.com>
S: Odd Fixes
F: drivers/staging/asus_oled/
STAGING - ATHEROS ATH6KL WIRELESS DRIVER
M: Luis R. Rodriguez <mcgrof@gmail.com>
M: Naveen Singh <nsingh@atheros.com>
S: Odd Fixes
F: drivers/staging/ath6kl/
STAGING - COMEDI
M: Ian Abbott <abbotti@mev.co.uk>
M: Mori Hess <fmhess@users.sourceforge.net>
S: Odd Fixes
F: drivers/staging/comedi/
STAGING - CRYSTAL HD VIDEO DECODER
M: Naren Sankar <nsankar@broadcom.com>
M: Jarod Wilson <jarod@wilsonet.com>
M: Scott Davilla <davilla@4pi.com>
M: Manu Abraham <abraham.manu@gmail.com>
S: Odd Fixes
F: drivers/staging/crystalhd/
STAGING - CYPRESS WESTBRIDGE SUPPORT
M: David Cross <david.cross@cypress.com>
S: Odd Fixes
F: drivers/staging/westbridge/
STAGING - ECHO CANCELLER
M: Steve Underwood <steveu@coppice.org>
M: David Rowe <david@rowetel.com>
S: Odd Fixes
F: drivers/staging/echo/
STAGING - FLARION FT1000 DRIVERS
M: Marek Belisko <marek.belisko@gmail.com>
S: Odd Fixes
F: drivers/staging/ft1000/
STAGING - FRONTIER TRANZPORT AND ALPHATRACK
M: David Täht <d@teklibre.com>
S: Odd Fixes
F: drivers/staging/frontier/
STAGING - HYPER-V (MICROSOFT)
M: Hank Janssen <hjanssen@microsoft.com>
M: Haiyang Zhang <haiyangz@microsoft.com>
S: Odd Fixes
F: drivers/staging/hv/
STAGING - INDUSTRIAL IO
M: Jonathan Cameron <jic23@cam.ac.uk>
L: linux-iio@vger.kernel.org
S: Odd Fixes
F: drivers/staging/iio/
STAGING - LIRC (LINUX INFRARED REMOTE CONTROL) DRIVERS
M: Jarod Wilson <jarod@wilsonet.com>
W: http://www.lirc.org/
S: Odd Fixes
F: drivers/staging/lirc/
STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
M: Andres Salomon <dilinger@queued.net>
M: Chris Ball <cjb@laptop.org>
M: Jon Nettleton <jon.nettleton@gmail.com>
W: http://wiki.laptop.org/go/DCON
S: Odd Fixes
F: drivers/staging/olpc_dcon/
STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER
M: Willy Tarreau <willy@meta-x.org>
S: Odd Fixes
F: drivers/staging/panel/
STAGING - REALTEK RTL8712U DRIVERS
M: Larry Finger <Larry.Finger@lwfinger.net>
M: Florian Schilhabel <florian.c.schilhabel@googlemail.com>.
S: Odd Fixes
F: drivers/staging/rtl8712/
STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
M: Teddy Wang <teddy.wang@siliconmotion.com.cn>
S: Odd Fixes
F: drivers/staging/sm7xx/
STAGING - SOFTLOGIC 6x10 MPEG CODEC
M: Ben Collins <bcollins@bluecherry.net>
S: Odd Fixes
F: drivers/staging/solo6x10/
STAGING - SPEAKUP CONSOLE SPEECH DRIVER
M: William Hubbs <w.d.hubbs@gmail.com>
M: Chris Brannon <chris@the-brannons.com>
M: Kirk Reiser <kirk@braille.uwo.ca>
M: Samuel Thibault <samuel.thibault@ens-lyon.org>
L: speakup@braille.uwo.ca
W: http://www.linux-speakup.org/
S: Odd Fixes
F: drivers/staging/speakup/
STAGING - TI DSP BRIDGE DRIVERS
M: Omar Ramirez Luna <omar.ramirez@ti.com>
S: Odd Fixes
F: drivers/staging/tidspbridge/
STAGING - TRIDENT TVMASTER TMxxxx USB VIDEO CAPTURE DRIVERS
L: linux-media@vger.kernel.org
S: Odd Fixes
F: drivers/staging/tm6000/
STAGING - USB ENE SM/MS CARD READER DRIVER
M: Al Cho <acho@novell.com>
S: Odd Fixes
F: drivers/staging/keucr/
STAGING - VIA VT665X DRIVERS
M: Forest Bond <forest@alittletooquiet.net>
S: Odd Fixes
F: drivers/staging/vt665?/
STAGING - WINBOND IS89C35 WLAN USB DRIVER
M: Pavel Machek <pavel@ucw.cz>
S: Odd Fixes
F: drivers/staging/winbond/
STAGING - XGI Z7,Z9,Z11 PCI DISPLAY DRIVER
M: Arnaud Patard <apatard@mandriva.com>
S: Odd Fixes
F: drivers/staging/xgifb/
STARFIRE/DURALAN NETWORK DRIVER
M: Ion Badulescu <ionut@badula.org>
S: Odd Fixes
@ -6594,13 +6734,6 @@ W: http://pegasus2.sourceforge.net/
S: Maintained
F: drivers/net/usb/rtl8150.c
USB SE401 DRIVER
L: linux-usb@vger.kernel.org
W: http://www.chello.nl/~j.vreeken/se401/
S: Orphan
F: Documentation/video4linux/se401.txt
F: drivers/staging/se401/
USB SERIAL BELKIN F5U103 DRIVER
M: William Greathouse <wgreathouse@smva.com>
L: linux-usb@vger.kernel.org

View File

@ -12,34 +12,14 @@
#include <linux/interrupt.h>
#include <linux/mfd/tc3589x.h>
#include <linux/input/matrix_keypad.h>
#include <../drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h>
#include <mach/gpio.h>
#include <mach/irqs.h>
#include "board-mop500.h"
/*
* Synaptics RMI4 touchscreen interface on the U8500 UIB
*/
/*
* Descriptor structure.
* Describes the number of i2c devices on the bus that speak RMI.
*/
static struct synaptics_rmi4_platform_data rmi4_i2c_dev_platformdata = {
.irq_number = NOMADIK_GPIO_TO_IRQ(84),
.irq_type = (IRQF_TRIGGER_FALLING | IRQF_SHARED),
.x_flip = false,
.y_flip = true,
.regulator_en = false,
};
static struct i2c_board_info __initdata mop500_i2c3_devices_u8500[] = {
{
I2C_BOARD_INFO("synaptics_rmi4_i2c", 0x4B),
.platform_data = &rmi4_i2c_dev_platformdata,
},
/* Dummy data that can be overridden by staging driver */
struct i2c_board_info __initdata __weak mop500_i2c3_devices_u8500[] = {
};
/*

View File

@ -24,10 +24,6 @@ menuconfig STAGING
if STAGING
source "drivers/staging/tty/Kconfig"
source "drivers/staging/generic_serial/Kconfig"
source "drivers/staging/et131x/Kconfig"
source "drivers/staging/slicoss/Kconfig"
@ -100,8 +96,6 @@ source "drivers/staging/sep/Kconfig"
source "drivers/staging/iio/Kconfig"
source "drivers/staging/cs5535_gpio/Kconfig"
source "drivers/staging/zram/Kconfig"
source "drivers/staging/zcache/Kconfig"
@ -120,8 +114,6 @@ source "drivers/staging/cxt1e1/Kconfig"
source "drivers/staging/xgifb/Kconfig"
source "drivers/staging/msm/Kconfig"
source "drivers/staging/lirc/Kconfig"
source "drivers/staging/easycap/Kconfig"
@ -132,8 +124,6 @@ source "drivers/staging/tidspbridge/Kconfig"
source "drivers/staging/quickstart/Kconfig"
source "drivers/staging/westbridge/Kconfig"
source "drivers/staging/sbe-2t3e3/Kconfig"
source "drivers/staging/ath6kl/Kconfig"

View File

@ -3,8 +3,6 @@
# fix for build system bug...
obj-$(CONFIG_STAGING) += staging.o
obj-y += tty/
obj-y += generic_serial/
obj-$(CONFIG_ET131X) += et131x/
obj-$(CONFIG_SLICOSS) += slicoss/
obj-$(CONFIG_VIDEO_GO7007) += go7007/
@ -41,7 +39,6 @@ obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio/
obj-$(CONFIG_ZRAM) += zram/
obj-$(CONFIG_XVMALLOC) += zram/
obj-$(CONFIG_ZCACHE) += zcache/
@ -52,12 +49,10 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
obj-$(CONFIG_CRYSTALHD) += crystalhd/
obj-$(CONFIG_CXT1E1) += cxt1e1/
obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_MSM_STAGING) += msm/
obj-$(CONFIG_EASYCAP) += easycap/
obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
obj-$(CONFIG_WESTBRIDGE_ASTORIA) += westbridge/astoria/
obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/
obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/
obj-$(CONFIG_USB_ENESTORAGE) += keucr/

View File

@ -1,5 +1,3 @@
comment "Altera FPGA firmware download module"
config ALTERA_STAPL
tristate "Altera FPGA firmware download module"
depends on I2C

View File

@ -1,3 +1,3 @@
altera-stapl-objs = altera-lpt.o altera-jtag.o altera-comp.o altera.o
altera-stapl-y := altera-lpt.o altera-jtag.o altera-comp.o altera.o
obj-$(CONFIG_ALTERA_STAPL) += altera-stapl.o

View File

@ -2430,16 +2430,23 @@ int altera_init(struct altera_config *config, const struct firmware *fw)
int index = 0;
s32 offset = 0L;
s32 error_address = 0L;
int retval = 0;
key = kzalloc(33 * sizeof(char), GFP_KERNEL);
if (!key)
return -ENOMEM;
value = kzalloc(257 * sizeof(char), GFP_KERNEL);
if (!value)
return -ENOMEM;
key = kzalloc(33, GFP_KERNEL);
if (!key) {
retval = -ENOMEM;
goto out;
}
value = kzalloc(257, GFP_KERNEL);
if (!value) {
retval = -ENOMEM;
goto free_key;
}
astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL);
if (!astate)
return -ENOMEM;
if (!astate) {
retval = -ENOMEM;
goto free_value;
}
astate->config = config;
if (!astate->config->jtag_io) {
@ -2518,10 +2525,12 @@ int altera_init(struct altera_config *config, const struct firmware *fw)
} else if (exec_result)
printk(KERN_ERR "%s: error %d\n", __func__, exec_result);
kfree(key);
kfree(value);
kfree(astate);
return 0;
free_value:
kfree(value);
free_key:
kfree(key);
out:
return retval;
}
EXPORT_SYMBOL(altera_init);

View File

@ -1,7 +1,7 @@
TODO:
We are working hard on cleaning up the driver. There's sooooooooo much todo
so instead of editign this file please use the wiki:
so instead of editing this file please use the wiki:
http://wireless.kernel.org/en/users/Drivers/ath6kl

View File

@ -954,9 +954,13 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
const char *filename;
const struct firmware *fw_entry;
u32 fw_entry_size;
u8 **buf;
size_t *buf_len;
switch (file) {
case AR6K_OTP_FILE:
buf = &ar->fw_otp;
buf_len = &ar->fw_otp_len;
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
filename = AR6003_REV1_OTP_FILE;
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
@ -970,6 +974,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
break;
case AR6K_FIRMWARE_FILE:
buf = &ar->fw;
buf_len = &ar->fw_len;
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
filename = AR6003_REV1_FIRMWARE_FILE;
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
@ -1028,6 +1034,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
break;
case AR6K_PATCH_FILE:
buf = &ar->fw_patch;
buf_len = &ar->fw_patch_len;
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
filename = AR6003_REV1_PATCH_FILE;
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
@ -1041,6 +1049,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
break;
case AR6K_BOARD_DATA_FILE:
buf = &ar->fw_data;
buf_len = &ar->fw_data_len;
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
filename = AR6003_REV1_BOARD_DATA_FILE;
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
@ -1057,23 +1067,29 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
return A_ERROR;
}
if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
{
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
return A_ENOENT;
if (*buf == NULL) {
if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
return A_ENOENT;
}
*buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
*buf_len = fw_entry->size;
A_RELEASE_FIRMWARE(fw_entry);
}
#ifdef SOFTMAC_FILE_USED
if (file==AR6K_BOARD_DATA_FILE && fw_entry->data) {
ar6000_softmac_update(ar, (u8 *)fw_entry->data, fw_entry->size);
if (file==AR6K_BOARD_DATA_FILE && *buf_len) {
ar6000_softmac_update(ar, *buf, *buf_len);
}
#endif
fw_entry_size = fw_entry->size;
fw_entry_size = *buf_len;
/* Load extended board data for AR6003 */
if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) {
if ((file==AR6K_BOARD_DATA_FILE) && *buf) {
u32 board_ext_address;
u32 board_ext_data_size;
u32 board_data_size;
@ -1089,14 +1105,13 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
/* check whether the target has allocated memory for extended board data and file contains extended board data */
if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) {
if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) {
u32 param;
status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(fw_entry->data + board_data_size), board_ext_data_size);
status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size);
if (status) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
A_RELEASE_FIRMWARE(fw_entry);
return A_ERROR;
}
@ -1110,17 +1125,16 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
}
if (compressed) {
status = BMIFastDownload(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size);
status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size);
} else {
status = BMIWriteMemory(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size);
status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size);
}
if (status) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
A_RELEASE_FIRMWARE(fw_entry);
return A_ERROR;
}
A_RELEASE_FIRMWARE(fw_entry);
return 0;
}
@ -2088,6 +2102,11 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister)
ar6000_remove_ap_interface();
#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
kfree(ar->fw_otp);
kfree(ar->fw);
kfree(ar->fw_patch);
kfree(ar->fw_data);
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
}
@ -4114,6 +4133,13 @@ ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver)
ar->arVersion.wlan_ver = sw_ver;
ar->arVersion.abi_ver = abi_ver;
snprintf(ar->wdev->wiphy->fw_version, sizeof(ar->wdev->wiphy->fw_version),
"%u:%u:%u:%u",
(ar->arVersion.wlan_ver & 0xf0000000) >> 28,
(ar->arVersion.wlan_ver & 0x0f000000) >> 24,
(ar->arVersion.wlan_ver & 0x00ff0000) >> 16,
(ar->arVersion.wlan_ver & 0x0000ffff));
/* Indicate to the waiting thread that the ready event was received */
ar->arWmiReady = true;
wake_up(&arEvent);

View File

@ -24,6 +24,7 @@
#include <linux/wireless.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <net/netlink.h>
#include "ar6000_drv.h"
@ -867,26 +868,31 @@ ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
if(ar->scan_request)
{
/* Translate data to cfg80211 mgmt format */
if (ar->arWmi)
wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
if (!ar->scan_request)
return;
cfg80211_scan_done(ar->scan_request,
((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
if ((status == A_ECANCELED) || (status == A_EBUSY)) {
cfg80211_scan_done(ar->scan_request, true);
goto out;
}
if(ar->scan_request->n_ssids &&
ar->scan_request->ssids[0].ssid_len) {
/* Translate data to cfg80211 mgmt format */
wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
cfg80211_scan_done(ar->scan_request, false);
if(ar->scan_request->n_ssids &&
ar->scan_request->ssids[0].ssid_len) {
u8 i;
for (i = 0; i < ar->scan_request->n_ssids; i++) {
wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
0, NULL);
wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
0, NULL);
}
}
ar->scan_request = NULL;
}
out:
ar->scan_request = NULL;
}
static int
@ -1453,6 +1459,159 @@ ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
return 0;
}
#ifdef CONFIG_NL80211_TESTMODE
enum ar6k_testmode_attr {
__AR6K_TM_ATTR_INVALID = 0,
AR6K_TM_ATTR_CMD = 1,
AR6K_TM_ATTR_DATA = 2,
/* keep last */
__AR6K_TM_ATTR_AFTER_LAST,
AR6K_TM_ATTR_MAX = __AR6K_TM_ATTR_AFTER_LAST - 1
};
enum ar6k_testmode_cmd {
AR6K_TM_CMD_TCMD = 0,
AR6K_TM_CMD_RX_REPORT = 1,
};
#define AR6K_TM_DATA_MAX_LEN 5000
static const struct nla_policy ar6k_testmode_policy[AR6K_TM_ATTR_MAX + 1] = {
[AR6K_TM_ATTR_CMD] = { .type = NLA_U32 },
[AR6K_TM_ATTR_DATA] = { .type = NLA_BINARY,
.len = AR6K_TM_DATA_MAX_LEN },
};
void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
int buf_len)
{
if (down_interruptible(&ar->arSem))
return;
kfree(ar->tcmd_rx_report);
ar->tcmd_rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
ar->tcmd_rx_report_len = buf_len;
up(&ar->arSem);
wake_up(&arEvent);
}
static int ar6000_testmode_rx_report(struct ar6_softc *ar, void *buf,
int buf_len, struct sk_buff *skb)
{
int ret = 0;
long left;
if (down_interruptible(&ar->arSem))
return -ERESTARTSYS;
if (ar->arWmiReady == false) {
ret = -EIO;
goto out;
}
if (ar->bIsDestroyProgress) {
ret = -EBUSY;
goto out;
}
WARN_ON(ar->tcmd_rx_report != NULL);
WARN_ON(ar->tcmd_rx_report_len > 0);
if (wmi_test_cmd(ar->arWmi, buf, buf_len) < 0) {
up(&ar->arSem);
return -EIO;
}
left = wait_event_interruptible_timeout(arEvent,
ar->tcmd_rx_report != NULL,
wmitimeout * HZ);
if (left == 0) {
ret = -ETIMEDOUT;
goto out;
} else if (left < 0) {
ret = left;
goto out;
}
if (ar->tcmd_rx_report == NULL || ar->tcmd_rx_report_len == 0) {
ret = -EINVAL;
goto out;
}
NLA_PUT(skb, AR6K_TM_ATTR_DATA, ar->tcmd_rx_report_len,
ar->tcmd_rx_report);
kfree(ar->tcmd_rx_report);
ar->tcmd_rx_report = NULL;
out:
up(&ar->arSem);
return ret;
nla_put_failure:
ret = -ENOBUFS;
goto out;
}
static int ar6k_testmode_cmd(struct wiphy *wiphy, void *data, int len)
{
struct ar6_softc *ar = wiphy_priv(wiphy);
struct nlattr *tb[AR6K_TM_ATTR_MAX + 1];
int err, buf_len, reply_len;
struct sk_buff *skb;
void *buf;
err = nla_parse(tb, AR6K_TM_ATTR_MAX, data, len,
ar6k_testmode_policy);
if (err)
return err;
if (!tb[AR6K_TM_ATTR_CMD])
return -EINVAL;
switch (nla_get_u32(tb[AR6K_TM_ATTR_CMD])) {
case AR6K_TM_CMD_TCMD:
if (!tb[AR6K_TM_ATTR_DATA])
return -EINVAL;
buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
wmi_test_cmd(ar->arWmi, buf, buf_len);
return 0;
break;
case AR6K_TM_CMD_RX_REPORT:
if (!tb[AR6K_TM_ATTR_DATA])
return -EINVAL;
buf = nla_data(tb[AR6K_TM_ATTR_DATA]);
buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]);
reply_len = nla_total_size(AR6K_TM_DATA_MAX_LEN);
skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
if (!skb)
return -ENOMEM;
err = ar6000_testmode_rx_report(ar, buf, buf_len, skb);
if (err < 0) {
kfree_skb(skb);
return err;
}
return cfg80211_testmode_reply(skb);
default:
return -EOPNOTSUPP;
}
}
#endif
static const
u32 cipher_suites[] = {
@ -1607,6 +1766,28 @@ static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
static int ar6k_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_pmksa *pmksa)
{
struct ar6_softc *ar = ar6k_priv(netdev);
return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, true);
}
static int ar6k_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_pmksa *pmksa)
{
struct ar6_softc *ar = ar6k_priv(netdev);
return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, false);
}
static int ar6k_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
{
struct ar6_softc *ar = ar6k_priv(netdev);
if (ar->arConnected)
return wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, false);
return 0;
}
static struct
cfg80211_ops ar6k_cfg80211_ops = {
.change_virtual_intf = ar6k_cfg80211_change_iface,
@ -1628,6 +1809,10 @@ cfg80211_ops ar6k_cfg80211_ops = {
.join_ibss = ar6k_cfg80211_join_ibss,
.leave_ibss = ar6k_cfg80211_leave_ibss,
.get_station = ar6k_get_station,
.set_pmksa = ar6k_set_pmksa,
.del_pmksa = ar6k_del_pmksa,
.flush_pmksa = ar6k_flush_pmksa,
CFG80211_TESTMODE_CMD(ar6k_testmode_cmd)
};
struct wireless_dev *

View File

@ -545,15 +545,9 @@ struct ar6_softc {
s8 arMaxRetries;
u8 arPhyCapability;
#ifdef CONFIG_HOST_TCMD_SUPPORT
u8 tcmdRxReport;
u32 tcmdRxTotalPkt;
s32 tcmdRxRssi;
u32 tcmdPm;
u32 arTargetMode;
u32 tcmdRxcrcErrPkt;
u32 tcmdRxsecErrPkt;
u16 tcmdRateCnt[TCMD_MAX_RATES];
u16 tcmdRateCntShortGuard[TCMD_MAX_RATES];
void *tcmd_rx_report;
int tcmd_rx_report_len;
#endif
AR6000_WLAN_STATE arWlanState;
struct ar_node_mapping arNodeMap[MAX_NODE_NUM];
@ -650,6 +644,15 @@ struct ar6_softc {
void *arApDev;
#endif
u8 arAutoAuthStage;
u8 *fw_otp;
size_t fw_otp_len;
u8 *fw;
size_t fw_len;
u8 *fw_patch;
size_t fw_patch_len;
u8 *fw_data;
size_t fw_data_len;
};
#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT

View File

@ -41,6 +41,17 @@ void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast);
#ifdef CONFIG_NL80211_TESTMODE
void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf,
int buf_len);
#else
static inline void ar6000_testmode_rx_report_event(struct ar6_softc *ar,
void *buf, int buf_len)
{
}
#endif
#endif /* _AR6K_CFG80211_H_ */

View File

@ -28,8 +28,6 @@
extern "C" {
#endif
#include <linux/version.h>
/*
* Host side Test Command support
*/

View File

@ -24,8 +24,6 @@
#ifndef _IEEE80211_IOCTL_H_
#define _IEEE80211_IOCTL_H_
#include <linux/version.h>
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -29,7 +29,6 @@
#ifdef __KERNEL__
#include <linux/version.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>

View File

@ -41,6 +41,7 @@
#include "a_debug.h"
#include "dbglog_api.h"
#include "roaming.h"
#include "cfg80211.h"
#define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
@ -4465,10 +4466,9 @@ wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance)
static int
wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len)
{
ar6000_testmode_rx_report_event(wmip->wmi_devt, datap, len);
A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
return 0;
return 0;
}
#endif /* CONFIG_HOST_TCMD_SUPPORT*/

View File

@ -131,7 +131,7 @@ DriverEntry.c, bcmfwup.c, ChipDetectTask.c, HaltnReset.c, InterfaceDDR.c */
// TODO - put PHS_SEND in Tx PHS_RECEIVE in Rx path ?
#define PHS_SEND (OTHERS<<16)
#define PHS_RECIEVE (OTHERS<<17)
#define PHS_RECEIVE (OTHERS<<17)
#define PHS_MODULE (OTHERS<<18)
#define INTF_INIT (OTHERS<<19)

View File

@ -157,7 +157,7 @@ static void read_bulk_callback(struct urb *urb)
{
/* Moving ahead by ETH_HLEN to the data ptr as received from FW */
skb_pull(skb, ETH_HLEN);
PHSRecieve(Adapter, pLeader->Vcid, skb, &skb->len,
PHSReceive(Adapter, pLeader->Vcid, skb, &skb->len,
NULL,bHeaderSupressionEnabled);
if(!Adapter->PackInfo[QueueIndex].bEthCSSupport)
@ -229,7 +229,7 @@ static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb)
/*
Function: InterfaceRx
Description: This is the hardware specific Function for Recieveing
Description: This is the hardware specific Function for Receiving
data packet/control packets from the device.
Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context

View File

@ -176,8 +176,8 @@ enum enLinkStatus {
PHY_SYNC_ACHIVED = 2,
LINKUP_IN_PROGRESS = 3,
LINKUP_DONE = 4,
DREG_RECIEVED = 5,
LINK_STATUS_RESET_RECIEVED = 6,
DREG_RECEIVED = 5,
LINK_STATUS_RESET_RECEIVED = 6,
PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7,
LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8,
COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW =9

View File

@ -1447,16 +1447,10 @@ static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount)
int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
{
INT uiRetVal =0;
uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
return Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
uiAddress, pucBuff, sSize);
if(uiRetVal < 0)
return uiRetVal;
return uiRetVal;
}
int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
{
int iRetVal;

View File

@ -209,7 +209,7 @@ int PHSTransmit(PMINI_ADAPTER Adapter,
return STATUS_SUCCESS;
}
int PHSRecieve(PMINI_ADAPTER Adapter,
int PHSReceive(PMINI_ADAPTER Adapter,
USHORT usVcid,
struct sk_buff *packet,
UINT *punPacketLen,
@ -223,7 +223,7 @@ int PHSRecieve(PMINI_ADAPTER Adapter,
UINT TotalBytesAdded = 0;
if(!bHeaderSuppressionEnabled)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet");
return ulPhsStatus;
}
@ -238,7 +238,7 @@ int PHSRecieve(PMINI_ADAPTER Adapter,
&nTotalsupressedPktHdrBytes,
&nStandardPktHdrLen);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
nTotalsupressedPktHdrBytes,nStandardPktHdrLen);
if(ulPhsStatus != STATUS_PHS_COMPRESSED)
@ -786,14 +786,14 @@ ULONG PhsDeCompress(IN void* pvContext,
if(pDeviceExtension == NULL)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n");
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Invalid Device Extension\n");
return ERR_PHS_INVALID_DEVICE_EXETENSION;
}
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n");
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Restoring header\n");
phsi = *((unsigned char *)(pvInputBuffer));
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x\n",phsi);
if(phsi == UNCOMPRESSED_PACKET )
{
return STATUS_PHS_NOCOMPRESSION;
@ -804,7 +804,7 @@ ULONG PhsDeCompress(IN void* pvContext,
uiVcid,&pstServiceFlowEntry);
if(nSFIndex == PHS_INVALID_TABLE_INDEX)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n");
return ERR_SF_MATCH_FAIL;
}
@ -1417,7 +1417,7 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
int in_buf_len = *header_size-1;
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
in_buf++;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n");
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"====>\n");
*header_size = 0;
if((decomp_phs_rules == NULL ))
@ -1425,7 +1425,7 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
tmp_memb = decomp_phs_rules;
//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
//*header_size = tmp_memb->u8PHSFLength;
phss = tmp_memb->u8PHSS;
phsf = tmp_memb->u8PHSF;
@ -1433,7 +1433,7 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
if(phss > MAX_PHS_LENGTHS)
phss = MAX_PHS_LENGTHS;
//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
while((phss > 0) && (size < in_buf_len))
{
bit = ((*phsm << i)& SUPPRESS);
@ -1441,13 +1441,13 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
if(bit == SUPPRESS)
{
*out_buf = *phsf;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d",
phss,*phsf,*out_buf);
}
else
{
*out_buf = *in_buf;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d",
phss,*in_buf,*out_buf);
in_buf++;
size++;

View File

@ -9,7 +9,7 @@ int PHSTransmit(PMINI_ADAPTER Adapter,
PUINT PacketLen,
UCHAR bEthCSSupport);
int PHSRecieve(PMINI_ADAPTER Adapter,
int PHSReceive(PMINI_ADAPTER Adapter,
USHORT usVcid,
struct sk_buff *packet,
UINT *punPacketLen,

View File

@ -23,7 +23,6 @@
#include <linux/wait.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/version.h>
#include <linux/stddef.h>
#include <linux/stat.h>
#include <linux/fcntl.h>

View File

@ -1,4 +1,5 @@
#include "headers.h"
#include <linux/sort.h>
/*
* File Name: sort.c
@ -10,54 +11,42 @@
* Copyright (c) 2007 Beceem Communications Pvt. Ltd
*/
static int compare_packet_info(void const *a, void const *b)
{
PacketInfo const *pa = a;
PacketInfo const *pb = b;
if (!pa->bValid || !pb->bValid)
return 0;
return pa->u8TrafficPriority - pb->u8TrafficPriority;
}
VOID SortPackInfo(PMINI_ADAPTER Adapter)
{
UINT nIndex1;
UINT nIndex2;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG,
DBG_LVL_ALL, "<=======");
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=======");
sort(Adapter->PackInfo, NO_OF_QUEUES, sizeof(PacketInfo),
compare_packet_info, NULL);
}
for(nIndex1 = 0; nIndex1 < NO_OF_QUEUES -2 ; nIndex1++)
{
for(nIndex2 = nIndex1 + 1 ; nIndex2 < NO_OF_QUEUES -1 ; nIndex2++)
{
if(Adapter->PackInfo[nIndex1].bValid && Adapter->PackInfo[nIndex2].bValid)
{
if(Adapter->PackInfo[nIndex2].u8TrafficPriority <
Adapter->PackInfo[nIndex1].u8TrafficPriority)
{
PacketInfo stTemppackInfo = Adapter->PackInfo[nIndex2];
Adapter->PackInfo[nIndex2] = Adapter->PackInfo[nIndex1];
Adapter->PackInfo[nIndex1] = stTemppackInfo;
static int compare_classifiers(void const *a, void const *b)
{
S_CLASSIFIER_RULE const *pa = a;
S_CLASSIFIER_RULE const *pb = b;
}
}
}
}
if (!pa->bUsed || !pb->bUsed)
return 0;
return pa->u8ClassifierRulePriority - pb->u8ClassifierRulePriority;
}
VOID SortClassifiers(PMINI_ADAPTER Adapter)
{
UINT nIndex1;
UINT nIndex2;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG,
DBG_LVL_ALL, "<=======");
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=======");
for(nIndex1 = 0; nIndex1 < MAX_CLASSIFIERS -1 ; nIndex1++)
{
for(nIndex2 = nIndex1 + 1 ; nIndex2 < MAX_CLASSIFIERS ; nIndex2++)
{
if(Adapter->astClassifierTable[nIndex1].bUsed && Adapter->astClassifierTable[nIndex2].bUsed)
{
if(Adapter->astClassifierTable[nIndex2].u8ClassifierRulePriority <
Adapter->astClassifierTable[nIndex1].u8ClassifierRulePriority)
{
S_CLASSIFIER_RULE stTempClassifierRule = Adapter->astClassifierTable[nIndex2];
Adapter->astClassifierTable[nIndex2] = Adapter->astClassifierTable[nIndex1];
Adapter->astClassifierTable[nIndex1] = stTempClassifierRule;
}
}
}
}
sort(Adapter->astClassifierTable, MAX_CLASSIFIERS,
sizeof(S_CLASSIFIER_RULE), compare_classifiers, NULL);
}

View File

@ -17,8 +17,8 @@
# common flags
subdir-ccflags-y := -DBCMDMA32
subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG -DBCMDBG_ASSERT
subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG
obj-$(CONFIG_BRCMUTIL) += util/
obj-$(CONFIG_BRCMUTIL) += brcmutil/
obj-$(CONFIG_BRCMFMAC) += brcmfmac/
obj-$(CONFIG_BRCMSMAC) += brcmsmac/

View File

@ -1,64 +1 @@
Broadcom brcmsmac (mac80211-based softmac PCIe) and brcmfmac (SDIO) drivers.
Completely open source host drivers, no binary object files.
Support for the following chips:
===============================
brcmsmac (PCIe)
Name Device ID
BCM4313 0x4727
BCM43224 0x4353
BCM43225 0x4357
brcmfmac (SDIO)
Name
BCM4329
Both brcmsmac and brcmfmac drivers require firmware files that need to be
separately downloaded.
Firmware
======================
Firmware is available from the Linux firmware repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
===============================================================
Broadcom brcmsmac driver
===============================================================
- Support for both 32 and 64 bit Linux kernels
Firmware installation
======================
Copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to
/lib/firmware/brcm (or wherever firmware is normally installed
on your system).
===============================================================
Broadcom brcmfmac driver
===============================================================
- Support for 32 bit Linux kernel, 64 bit untested
Firmware installation
======================
Copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt
to /lib/firmware/brcm (or wherever firmware is normally installed on your
system).
Contact Info:
=============
Brett Rudley brudley@broadcom.com
Henry Ptasinski henryp@broadcom.com
Dowan Kim dowan@broadcom.com
Roland Vossen rvossen@broadcom.com
Arend van Spriel arend@broadcom.com
For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211
refer to: http://linuxwireless.org/en/users/Drivers/brcm80211

View File

@ -2,14 +2,12 @@ To Do List for Broadcom Mac80211 driver before getting in mainline
Bugs
====
- Oops on AMPDU traffic, to be solved by new ucode (currently under test)
brcmfmac and brcmsmac
=====================
- ASSERTS not allowed in mainline, replace by warning + error handling
- Replace printk and WL_ERROR() with proper routines
- none known at this moment
brcmfmac
=====================
- Replace driver's proprietary ssb interface with generic kernel ssb module
- Build and test on 64 bit linux kernel
- ASSERTS deprecated in mainline, replace by warning + error handling
brcm80211 info page
=====================
http://linuxwireless.org/en/users/Drivers/brcm80211

View File

@ -16,23 +16,11 @@
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ccflags-y := \
-DARP_OFFLOAD_SUPPORT \
-DBCMLXSDMMC \
-DBCMPLATFORM_BUS \
-DBCMSDIO \
-DBDC \
-DBRCM_FULLMAC \
-DDHD_FIRSTREAD=64 \
-DDHD_SCHED \
-DDHD_SDALIGN=64 \
-DEMBEDDED_PLATFORM \
-DMAX_HDR_READ=64 \
-DMMC_SDIO_ABORT \
-DPKT_FILTER_SUPPORT \
-DSHOW_EVENTS \
-DTOE
-DBRCMF_FIRSTREAD=64 \
-DBRCMF_SDALIGN=64 \
-DMAX_HDR_READ=64
ccflags-$(CONFIG_BRCMDBG) += -DDHD_DEBUG
ccflags-$(CONFIG_BRCMDBG) += -DSHOW_EVENTS
ccflags-y += \
-Idrivers/staging/brcm80211/brcmfmac \
@ -40,17 +28,12 @@ ccflags-y += \
DHDOFILES = \
wl_cfg80211.o \
wl_iw.o \
dhd_cdc.o \
dhd_common.o \
dhd_custom_gpio.o \
dhd_sdio.o \
dhd_linux.o \
dhd_linux_sched.o \
bcmsdh.o \
bcmsdh_linux.o \
bcmsdh_sdmmc.o \
bcmsdh_sdmmc_linux.o
bcmsdh_sdmmc.o
obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
brcmfmac-objs += $(DHDOFILES)

View File

@ -1,2 +0,0 @@

View File

@ -1 +0,0 @@
#include "../util/aiutils.c"

View File

@ -1,98 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/if_ether.h>
typedef struct cdc_ioctl {
u32 cmd; /* ioctl command value */
u32 len; /* lower 16: output buflen; upper 16:
input buflen (excludes header) */
u32 flags; /* flag defns given below */
u32 status; /* status code returned from the device */
} cdc_ioctl_t;
/* Max valid buffer size that can be sent to the dongle */
#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
/* len field is divided into input and output buffer lengths */
#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected
response length, */
/* excluding IOCTL header */
#define CDCL_IOC_OUTLEN_SHIFT 0
#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length,
excluding IOCTL header */
#define CDCL_IOC_INLEN_SHIFT 16
/* CDC flag definitions */
#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */
#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */
#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */
#define CDCF_IOC_IF_SHIFT 12
#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl
req/resp pairing */
#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */
#define CDC_IOC_IF_IDX(flags) \
(((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)
#define CDC_IOC_ID(flags) \
(((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
#define CDC_GET_IF_IDX(hdr) \
((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT))
#define CDC_SET_IF_IDX(hdr, idx) \
((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \
((idx) << CDCF_IOC_IF_SHIFT)))
/*
* BDC header
*
* The BDC header is 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__UNUSED 0x03 /* Unassigned */
#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good
RX checksums */
#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
#define BDC_PRIORITY_MASK 0x7
#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */
/* FLOW CONTROL info only */
#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */
#define BDC_FLAG2_IF_MASK 0x0f /* APSTA: interface on which the
packet was received */
#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 bdc_header {
u8 flags; /* Flags */
u8 priority; /* 802.1d Priority 0:2 bits, 4:7 flow
control info for usb */
u8 flags2;
u8 rssi;
};

View File

@ -17,12 +17,6 @@
#ifndef _bcmchip_h_
#define _bcmchip_h_
/* Core reg address translation */
#define CORE_CC_REG(base, field) (base + offsetof(chipcregs_t, field))
#define CORE_BUS_REG(base, field) (base + offsetof(sdpcmd_regs_t, field))
#define CORE_SB(base, field) \
(base + SBCONFIGOFF + offsetof(sbconfig_t, field))
/* bcm4329 */
/* SDIO device core, ID 0x829 */
#define BCM4329_CORE_BUS_BASE 0x18011000
@ -31,5 +25,8 @@
/* 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_ */

View File

@ -1,113 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _sdio_api_h_
#define _sdio_api_h_
#define SDIOH_API_RC_SUCCESS (0x00)
#define SDIOH_API_RC_FAIL (0x01)
#define SDIOH_API_SUCCESS(status) (status == 0)
#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 */
#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */
#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */
#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */
#define SDIOH_DATA_PIO 0 /* PIO mode */
#define SDIOH_DATA_DMA 1 /* DMA mode */
typedef int SDIOH_API_RC;
/* SDio Host structure */
typedef struct sdioh_info sdioh_info_t;
/* callback function, taking one arg */
typedef void (*sdioh_cb_fn_t) (void *);
/* 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 sdioh_info_t *sdioh_attach(void *cfghdl, uint irq);
extern SDIOH_API_RC sdioh_detach(sdioh_info_t *si);
extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si,
sdioh_cb_fn_t fn, void *argh);
extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si);
/* query whether SD interrupt is enabled or not */
extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff);
/* enable or disable SD interrupt */
extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable);
#if defined(DHD_DEBUG)
extern bool sdioh_interrupt_pending(sdioh_info_t *si);
#endif
extern int sdioh_claim_host_and_lock(sdioh_info_t *si);
extern int sdioh_release_host_and_unlock(sdioh_info_t *si);
/* read or write one byte using cmd52 */
extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc,
uint addr, u8 *byte);
/* read or write 2/4 bytes using cmd53 */
extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type,
uint rw, uint fnc, uint addr,
u32 *word, uint nbyte);
/* read or write any buffer using cmd53 */
extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma,
uint fix_inc, uint rw, uint fnc_num,
u32 addr, uint regwidth,
u32 buflen, u8 *buffer,
struct sk_buff *pkt);
/* get cis data */
extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, u8 *cis,
u32 length);
extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, u32 addr,
u8 *data);
extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, u32 addr,
u8 *data);
/* query number of io functions */
extern uint sdioh_query_iofnum(sdioh_info_t *si);
/* handle iovars */
extern int sdioh_iovar_op(sdioh_info_t *si, const char *name,
void *params, int plen, void *arg, int len, bool set);
/* Issue abort to the specified function and clear controller as needed */
extern int sdioh_abort(sdioh_info_t *si, uint fnc);
/* Start and Stop SDIO without re-enumerating the SD card. */
extern int sdioh_start(sdioh_info_t *si, int stage);
extern int sdioh_stop(sdioh_info_t *si);
/* Reset and re-initialize the device */
extern int sdioh_sdio_reset(sdioh_info_t *si);
/* Helper function */
void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
#endif /* _sdio_api_h_ */

View File

@ -13,29 +13,59 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* ****************** BCMSDH Interface Functions *************************** */
/* ****************** SDIO CARD Interface Functions **************************/
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <bcmdefs.h>
#include <bcmdevs.h>
#include <bcmutils.h>
#include <hndsoc.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <bcmsdh.h> /* BRCM API for SDIO
clients (such as wl, dhd) */
#include <bcmsdbus.h> /* common SDIO/controller interface */
#include <sbsdio.h> /* BRCM sdio device core */
#include <sdio.h> /* sdio spec */
#include "dngl_stats.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 "sdio_host.h"
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
struct bcmsdh_info {
#define BRCMF_SD_ERROR_VAL 0x0001 /* Error */
#define BRCMF_SD_INFO_VAL 0x0002 /* Info */
#ifdef BCMDBG
#define BRCMF_SD_ERROR(x) \
do { \
if ((brcmf_sdio_msglevel & BRCMF_SD_ERROR_VAL) && \
net_ratelimit()) \
printk x; \
} while (0)
#define BRCMF_SD_INFO(x) \
do { \
if ((brcmf_sdio_msglevel & BRCMF_SD_INFO_VAL) && \
net_ratelimit()) \
printk x; \
} while (0)
#else /* BCMDBG */
#define BRCMF_SD_ERROR(x)
#define BRCMF_SD_INFO(x)
#endif /* BCMDBG */
/* debugging macros */
#define SDLX_MSG(x)
#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */
#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */
#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */
#define SDIOH_DATA_PIO 0 /* PIO mode */
#define SDIOH_DATA_DMA 1 /* DMA mode */
struct brcmf_sdio_card {
bool init_success; /* underlying driver successfully attached */
void *sdioh; /* handler for sdioh */
u32 vendevid; /* Target Vendor and Device ID on SD bus */
@ -43,282 +73,232 @@ struct bcmsdh_info {
reg_read/reg_write call */
u32 sbwad; /* Save backplane window address */
};
/**
* SDIO Host Controller info
*/
struct sdio_hc {
struct sdio_hc *next;
struct device *dev; /* platform device handle */
void *regs; /* SDIO Host Controller address */
struct brcmf_sdio_card *card;
void *ch;
unsigned int oob_irq;
unsigned long oob_flags; /* OOB Host specifiction
as edge and etc */
bool oob_irq_registered;
};
/* local copy of bcm sd handler */
bcmsdh_info_t *l_bcmsdh;
static struct brcmf_sdio_card *l_card;
#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
extern int sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL;
void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
static struct sdio_hc *sdhcinfo;
/* driver info, initialized when brcmf_sdio_register is called */
static struct brcmf_sdioh_driver drvinfo = { NULL, NULL };
/* Module parameters specific to each host-controller driver */
module_param(sd_msglevel, uint, 0);
extern uint sd_f2_blocksize;
module_param(sd_f2_blocksize, int, 0);
/* forward declarations */
int brcmf_sdio_probe(struct device *dev);
EXPORT_SYMBOL(brcmf_sdio_probe);
int brcmf_sdio_remove(struct device *dev);
EXPORT_SYMBOL(brcmf_sdio_remove);
struct brcmf_sdio_card*
brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq)
{
sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
}
#endif
struct brcmf_sdio_card *card;
bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq)
{
bcmsdh_info_t *bcmsdh;
bcmsdh = kzalloc(sizeof(bcmsdh_info_t), GFP_ATOMIC);
if (bcmsdh == NULL) {
BCMSDH_ERROR(("bcmsdh_attach: out of memory"));
card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC);
if (card == NULL) {
BRCMF_SD_ERROR(("sdcard_attach: out of memory"));
return NULL;
}
/* save the handler locally */
l_bcmsdh = bcmsdh;
l_card = card;
bcmsdh->sdioh = sdioh_attach(cfghdl, irq);
if (!bcmsdh->sdioh) {
bcmsdh_detach(bcmsdh);
card->sdioh = brcmf_sdioh_attach(cfghdl, irq);
if (!card->sdioh) {
brcmf_sdcard_detach(card);
return NULL;
}
bcmsdh->init_success = true;
card->init_success = true;
*regsva = (u32 *) SI_ENUM_BASE;
*regsva = SI_ENUM_BASE;
/* Report the BAR, to fix if needed */
bcmsdh->sbwad = SI_ENUM_BASE;
return bcmsdh;
card->sbwad = SI_ENUM_BASE;
return card;
}
int bcmsdh_detach(void *sdh)
int brcmf_sdcard_detach(struct brcmf_sdio_card *card)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
if (bcmsdh != NULL) {
if (bcmsdh->sdioh) {
sdioh_detach(bcmsdh->sdioh);
bcmsdh->sdioh = NULL;
if (card != NULL) {
if (card->sdioh) {
brcmf_sdioh_detach(card->sdioh);
card->sdioh = NULL;
}
kfree(bcmsdh);
kfree(card);
}
l_bcmsdh = NULL;
l_card = NULL;
return 0;
}
int
bcmsdh_iovar_op(void *sdh, const char *name,
brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
void *params, int plen, void *arg, int len, bool set)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg,
len, set);
}
bool bcmsdh_intr_query(void *sdh)
int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
bool on;
ASSERT(bcmsdh);
status = sdioh_interrupt_query(bcmsdh->sdioh, &on);
if (SDIOH_API_SUCCESS(status))
return false;
else
return on;
return brcmf_sdioh_interrupt_set(card->sdioh, true);
}
int bcmsdh_intr_enable(void *sdh)
int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
ASSERT(bcmsdh);
status = sdioh_interrupt_set(bcmsdh->sdioh, true);
return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
return brcmf_sdioh_interrupt_set(card->sdioh, false);
}
int bcmsdh_intr_disable(void *sdh)
int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
void (*fn)(void *), void *argh)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
ASSERT(bcmsdh);
status = sdioh_interrupt_set(bcmsdh->sdioh, false);
return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh);
}
int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
ASSERT(bcmsdh);
status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
return brcmf_sdioh_interrupt_deregister(card->sdioh);
}
int bcmsdh_intr_dereg(void *sdh)
u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
int *err)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
ASSERT(bcmsdh);
status = sdioh_interrupt_deregister(bcmsdh->sdioh);
return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
}
#if defined(DHD_DEBUG)
bool bcmsdh_intr_pending(void *sdh)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
ASSERT(sdh);
return sdioh_interrupt_pending(bcmsdh->sdioh);
}
#endif
int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
{
ASSERT(sdh);
/* don't support yet */
return -ENOTSUPP;
}
u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
int status;
s32 retry = 0;
#endif
u8 data = 0;
if (!bcmsdh)
bcmsdh = l_bcmsdh;
if (!card)
card = l_card;
ASSERT(bcmsdh->init_success);
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
do {
if (retry) /* wait for 1 ms till bus get settled down */
udelay(1000);
#endif
status =
sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr,
brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr,
(u8 *) &data);
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
} while (!SDIOH_API_SUCCESS(status)
} while (status != 0
&& (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
#endif
if (err)
*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
*err = status;
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
__func__, fnc_num, addr, data));
return data;
}
void
bcmsdh_cfg_write(void *sdh, uint fnc_num, u32 addr, u8 data, int *err)
brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
u8 data, int *err)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
int status;
s32 retry = 0;
#endif
if (!bcmsdh)
bcmsdh = l_bcmsdh;
if (!card)
card = l_card;
ASSERT(bcmsdh->init_success);
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
do {
if (retry) /* wait for 1 ms till bus get settled down */
udelay(1000);
#endif
status =
sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr,
brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr,
(u8 *) &data);
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
} while (!SDIOH_API_SUCCESS(status)
} while (status != 0
&& (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
#endif
if (err)
*err = SDIOH_API_SUCCESS(status) ? 0 : -EIO;
*err = status;
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
__func__, fnc_num, addr, data));
}
u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr, int *err)
u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
u32 addr, int *err)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
int status;
u32 data = 0;
if (!bcmsdh)
bcmsdh = l_bcmsdh;
if (!card)
card = l_card;
ASSERT(bcmsdh->init_success);
status =
sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ,
fnc_num, addr, &data, 4);
status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
SDIOH_READ, fnc_num, addr, &data, 4);
if (err)
*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
*err = status;
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
__func__, fnc_num, addr, data));
return data;
}
void
bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr, u32 data,
int *err)
brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num,
u32 addr, u32 data, int *err)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
int status;
if (!bcmsdh)
bcmsdh = l_bcmsdh;
ASSERT(bcmsdh->init_success);
if (!card)
card = l_card;
status =
sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
SDIOH_WRITE, fnc_num, addr, &data, 4);
if (err)
*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
*err = status;
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
__func__, fnc_num, addr, data));
}
int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length)
int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis,
uint length)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
int status;
u8 *tmp_buf, *tmp_ptr;
u8 *ptr;
bool ascii = func & ~0xf;
func &= 0x7;
if (!bcmsdh)
bcmsdh = l_bcmsdh;
if (!card)
card = l_card;
ASSERT(bcmsdh->init_success);
ASSERT(cis);
ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length);
status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length);
if (ascii) {
/* Move binary bits to tmp and format them
into the provided buffer. */
tmp_buf = kmalloc(length, GFP_ATOMIC);
if (tmp_buf == NULL) {
BCMSDH_ERROR(("%s: out of memory\n", __func__));
BRCMF_SD_ERROR(("%s: out of memory\n", __func__));
return -ENOMEM;
}
memcpy(tmp_buf, cis, length);
@ -331,60 +311,60 @@ int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length)
kfree(tmp_buf);
}
return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
return status;
}
static int bcmsdhsdio_set_sbaddr_window(void *sdh, u32 address)
static int
brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address)
{
int err = 0;
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
(address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
if (!err)
bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
(address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
SBSDIO_FUNC1_SBADDRMID,
(address >> 16) & SBSDIO_SBADDRMID_MASK,
&err);
if (!err)
bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
(address >> 24) & SBSDIO_SBADDRHIGH_MASK,
&err);
brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
SBSDIO_FUNC1_SBADDRHIGH,
(address >> 24) & SBSDIO_SBADDRHIGH_MASK,
&err);
return err;
}
u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size)
u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
int status;
u32 word = 0;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
if (!bcmsdh)
bcmsdh = l_bcmsdh;
if (!card)
card = l_card;
ASSERT(bcmsdh->init_success);
if (bar0 != bcmsdh->sbwad) {
if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))
if (bar0 != card->sbwad) {
if (brcmf_sdcard_set_sbaddr_window(card, bar0))
return 0xFFFFFFFF;
bcmsdh->sbwad = bar0;
card->sbwad = bar0;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
if (size == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
card->regfail = (status != 0);
BCMSDH_INFO(("u32data = 0x%x\n", word));
BRCMF_SD_INFO(("u32data = 0x%x\n", word));
/* if ok, return appropriately masked word */
if (SDIOH_API_SUCCESS(status)) {
if (status == 0) {
switch (size) {
case sizeof(u8):
return word & 0xff;
@ -393,90 +373,86 @@ u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size)
case sizeof(u32):
return word;
default:
bcmsdh->regfail = true;
card->regfail = true;
}
}
/* otherwise, bad sdio access or invalid size */
BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
addr, size));
return 0xFFFFFFFF;
}
u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data)
u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
u32 data)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
int status;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
__func__, addr, size * 8, data));
if (!bcmsdh)
bcmsdh = l_bcmsdh;
if (!card)
card = l_card;
ASSERT(bcmsdh->init_success);
if (bar0 != bcmsdh->sbwad) {
err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
if (bar0 != card->sbwad) {
err = brcmf_sdcard_set_sbaddr_window(card, bar0);
if (err)
return err;
bcmsdh->sbwad = bar0;
card->sbwad = bar0;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
if (size == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
status =
sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
card->regfail = (status != 0);
if (SDIOH_API_SUCCESS(status))
if (status == 0)
return 0;
BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
__func__, data, addr, size));
return 0xFFFFFFFF;
}
bool bcmsdh_regfail(void *sdh)
bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card)
{
return ((bcmsdh_info_t *) sdh)->regfail;
return card->regfail;
}
int
bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
u8 *buf, uint nbytes, struct sk_buff *pkt,
bcmsdh_cmplt_fn_t complete, void *handle)
brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
uint flags,
u8 *buf, uint nbytes, struct sk_buff *pkt,
void (*complete)(void *handle, int status,
bool sync_waiting),
void *handle)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
int status;
uint incr_fix;
uint width;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
ASSERT(bcmsdh);
ASSERT(bcmsdh->init_success);
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
__func__, fn, addr, nbytes));
/* Async not implemented yet */
ASSERT(!(flags & SDIO_REQ_ASYNC));
if (flags & SDIO_REQ_ASYNC)
return -ENOTSUPP;
if (bar0 != bcmsdh->sbwad) {
err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
if (bar0 != card->sbwad) {
err = brcmf_sdcard_set_sbaddr_window(card, bar0);
if (err)
return err;
bcmsdh->sbwad = bar0;
card->sbwad = bar0;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
@ -486,42 +462,37 @@ bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
if (width == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
SDIOH_READ, fn, addr, width, nbytes, buf,
pkt);
status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
return status;
}
int
bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
u8 *buf, uint nbytes, void *pkt,
bcmsdh_cmplt_fn_t complete, void *handle)
brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
uint flags, u8 *buf, uint nbytes, void *pkt,
void (*complete)(void *handle, int status,
bool sync_waiting),
void *handle)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
uint incr_fix;
uint width;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
ASSERT(bcmsdh);
ASSERT(bcmsdh->init_success);
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
__func__, fn, addr, nbytes));
/* Async not implemented yet */
ASSERT(!(flags & SDIO_REQ_ASYNC));
if (flags & SDIO_REQ_ASYNC)
return -ENOTSUPP;
if (bar0 != bcmsdh->sbwad) {
err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
if (bar0 != card->sbwad) {
err = brcmf_sdcard_set_sbaddr_window(card, bar0);
if (err)
return err;
bcmsdh->sbwad = bar0;
card->sbwad = bar0;
}
addr &= SBSDIO_SB_OFT_ADDR_MASK;
@ -531,101 +502,141 @@ bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
if (width == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
SDIOH_WRITE, fn, addr, width, nbytes, buf,
pkt);
return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
}
int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes)
int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
u8 *buf, uint nbytes)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
SDIOH_API_RC status;
ASSERT(bcmsdh);
ASSERT(bcmsdh->init_success);
ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
addr &= SBSDIO_SB_OFT_ADDR_MASK;
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
status =
sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC,
(rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
addr, 4, nbytes, buf, NULL);
return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
addr, 4, nbytes, buf, NULL);
}
int bcmsdh_abort(void *sdh, uint fn)
int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
return sdioh_abort(bcmsdh->sdioh, fn);
return brcmf_sdioh_abort(card->sdioh, fn);
}
int bcmsdh_start(void *sdh, int stage)
int brcmf_sdcard_query_device(struct brcmf_sdio_card *card)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
return sdioh_start(bcmsdh->sdioh, stage);
card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
return card->vendevid;
}
int bcmsdh_stop(void *sdh)
u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
if (!card)
card = l_card;
return sdioh_stop(bcmsdh->sdioh);
return card->sbwad;
}
int bcmsdh_query_device(void *sdh)
int brcmf_sdio_probe(struct device *dev)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
bcmsdh->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
return bcmsdh->vendevid;
struct sdio_hc *sdhc = NULL;
u32 regs = 0;
struct brcmf_sdio_card *card = NULL;
int irq = 0;
u32 vendevid;
unsigned long irq_flags = 0;
/* allocate SDIO Host Controller state info */
sdhc = kzalloc(sizeof(struct sdio_hc), GFP_ATOMIC);
if (!sdhc) {
SDLX_MSG(("%s: out of memory\n", __func__));
goto err;
}
sdhc->dev = (void *)dev;
card = brcmf_sdcard_attach((void *)0, &regs, irq);
if (!card) {
SDLX_MSG(("%s: attach failed\n", __func__));
goto err;
}
sdhc->card = card;
sdhc->oob_irq = irq;
sdhc->oob_flags = irq_flags;
sdhc->oob_irq_registered = false; /* to make sure.. */
/* chain SDIO Host Controller info together */
sdhc->next = sdhcinfo;
sdhcinfo = sdhc;
/* Read the vendor/device ID from the CIS */
vendevid = brcmf_sdcard_query_device(card);
/* try to attach to the target device */
sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
0, 0, 0, 0, regs, card);
if (!sdhc->ch) {
SDLX_MSG(("%s: device attach failed\n", __func__));
goto err;
}
return 0;
/* error handling */
err:
if (sdhc) {
if (sdhc->card)
brcmf_sdcard_detach(sdhc->card);
kfree(sdhc);
}
return -ENODEV;
}
uint bcmsdh_query_iofnum(void *sdh)
int brcmf_sdio_remove(struct device *dev)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
struct sdio_hc *sdhc, *prev;
if (!bcmsdh)
bcmsdh = l_bcmsdh;
sdhc = sdhcinfo;
drvinfo.detach(sdhc->ch);
brcmf_sdcard_detach(sdhc->card);
/* find the SDIO Host Controller state for this pdev
and take it out from the list */
for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
if (sdhc->dev == (void *)dev) {
if (prev)
prev->next = sdhc->next;
else
sdhcinfo = NULL;
break;
}
prev = sdhc;
}
if (!sdhc) {
SDLX_MSG(("%s: failed\n", __func__));
return 0;
}
return sdioh_query_iofnum(bcmsdh->sdioh);
}
int bcmsdh_reset(bcmsdh_info_t *sdh)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
return sdioh_sdio_reset(bcmsdh->sdioh);
}
void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh)
{
ASSERT(sdh);
return sdh->sdioh;
}
/* Function to pass device-status bits to DHD. */
u32 bcmsdh_get_dstatus(void *sdh)
{
/* release SDIO Host Controller info */
kfree(sdhc);
return 0;
}
u32 bcmsdh_cur_sbwad(void *sdh)
int brcmf_sdio_register(struct brcmf_sdioh_driver *driver)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
drvinfo = *driver;
if (!bcmsdh)
bcmsdh = l_bcmsdh;
return bcmsdh->sbwad;
SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
return brcmf_sdio_function_init();
}
void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev)
void brcmf_sdio_unregister(void)
{
return;
brcmf_sdio_function_cleanup();
}
void brcmf_sdio_wdtmr_enable(bool enable)
{
if (enable)
brcmf_sdbrcm_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms);
else
brcmf_sdbrcm_wd_timer(sdhcinfo->ch, 0);
}

View File

@ -1,386 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* @file bcmsdh_linux.c
*/
#define __UNDEF_NO_VERSION__
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/completion.h>
#include <pcicfg.h>
#include <bcmdefs.h>
#include <bcmdevs.h>
#include <bcmutils.h>
#if defined(OOB_INTR_ONLY)
#include <linux/irq.h>
extern void dhdsdio_isr(void *args);
#include <dngl_stats.h>
#include <dhd.h>
#endif /* defined(OOB_INTR_ONLY) */
#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270)
#if !defined(BCMPLATFORM_BUS)
#define BCMPLATFORM_BUS
#endif /* !defined(BCMPLATFORM_BUS) */
#include <linux/platform_device.h>
#endif /* CONFIG_MACH_SANDGATE2G */
#include "dngl_stats.h"
#include "dhd.h"
/**
* SDIO Host Controller info
*/
typedef struct bcmsdh_hc bcmsdh_hc_t;
struct bcmsdh_hc {
bcmsdh_hc_t *next;
#ifdef BCMPLATFORM_BUS
struct device *dev; /* platform device handle */
#else
struct pci_dev *dev; /* pci device handle */
#endif /* BCMPLATFORM_BUS */
void *regs; /* SDIO Host Controller address */
bcmsdh_info_t *sdh; /* SDIO Host Controller handle */
void *ch;
unsigned int oob_irq;
unsigned long oob_flags; /* OOB Host specifiction
as edge and etc */
bool oob_irq_registered;
#if defined(OOB_INTR_ONLY)
spinlock_t irq_lock;
#endif
};
static bcmsdh_hc_t *sdhcinfo;
/* driver info, initialized when bcmsdh_register is called */
static bcmsdh_driver_t drvinfo = { NULL, NULL };
/* debugging macros */
#define SDLX_MSG(x)
/**
* Checks to see if vendor and device IDs match a supported SDIO Host Controller.
*/
bool bcmsdh_chipmatch(u16 vendor, u16 device)
{
/* Add other vendors and devices as required */
#ifdef BCMSDIOH_STD
/* Check for Arasan host controller */
if (vendor == VENDOR_SI_IMAGE)
return true;
/* Check for BRCM 27XX Standard host controller */
if (device == BCM27XX_SDIOH_ID && vendor == PCI_VENDOR_ID_BROADCOM)
return true;
/* Check for BRCM Standard host controller */
if (device == SDIOH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM)
return true;
/* Check for TI PCIxx21 Standard host controller */
if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI)
return true;
if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI)
return true;
/* Ricoh R5C822 Standard SDIO Host */
if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH)
return true;
/* JMicron Standard SDIO Host */
if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON)
return true;
#endif /* BCMSDIOH_STD */
#ifdef BCMSDIOH_SPI
/* This is the PciSpiHost. */
if (device == SPIH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) {
return true;
}
#endif /* BCMSDIOH_SPI */
return false;
}
#if defined(BCMPLATFORM_BUS)
#if defined(BCMLXSDMMC)
/* forward declarations */
int bcmsdh_probe(struct device *dev);
EXPORT_SYMBOL(bcmsdh_probe);
int bcmsdh_remove(struct device *dev);
EXPORT_SYMBOL(bcmsdh_remove);
#else
/* forward declarations */
static int __devinit bcmsdh_probe(struct device *dev);
static int __devexit bcmsdh_remove(struct device *dev);
#endif /* BCMLXSDMMC */
#ifndef BCMLXSDMMC
static
#endif /* BCMLXSDMMC */
int bcmsdh_probe(struct device *dev)
{
bcmsdh_hc_t *sdhc = NULL;
unsigned long regs = 0;
bcmsdh_info_t *sdh = NULL;
#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
struct platform_device *pdev;
struct resource *r;
#endif /* BCMLXSDMMC */
int irq = 0;
u32 vendevid;
unsigned long irq_flags = 0;
#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
pdev = to_platform_device(dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (!r || irq == NO_IRQ)
return -ENXIO;
#endif /* BCMLXSDMMC */
#if defined(OOB_INTR_ONLY)
#ifdef HW_OOB
irq_flags =
IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
IORESOURCE_IRQ_SHAREABLE;
#else
irq_flags = IRQF_TRIGGER_FALLING;
#endif /* HW_OOB */
irq = dhd_customer_oob_irq_map(&irq_flags);
if (irq < 0) {
SDLX_MSG(("%s: Host irq is not defined\n", __func__));
return 1;
}
#endif /* defined(OOB_INTR_ONLY) */
/* allocate SDIO Host Controller state info */
sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC);
if (!sdhc) {
SDLX_MSG(("%s: out of memory\n", __func__));
goto err;
}
sdhc->dev = (void *)dev;
#ifdef BCMLXSDMMC
sdh = bcmsdh_attach((void *)0, (void **)&regs, irq);
if (!sdh) {
SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
goto err;
}
#else
sdh = bcmsdh_attach((void *)r->start, (void **)&regs, irq);
if (!sdh) {
SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
goto err;
}
#endif /* BCMLXSDMMC */
sdhc->sdh = sdh;
sdhc->oob_irq = irq;
sdhc->oob_flags = irq_flags;
sdhc->oob_irq_registered = false; /* to make sure.. */
#if defined(OOB_INTR_ONLY)
spin_lock_init(&sdhc->irq_lock);
#endif
/* chain SDIO Host Controller info together */
sdhc->next = sdhcinfo;
sdhcinfo = sdhc;
/* Read the vendor/device ID from the CIS */
vendevid = bcmsdh_query_device(sdh);
/* try to attach to the target device */
sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
0, 0, 0, 0, (void *)regs, sdh);
if (!sdhc->ch) {
SDLX_MSG(("%s: device attach failed\n", __func__));
goto err;
}
return 0;
/* error handling */
err:
if (sdhc) {
if (sdhc->sdh)
bcmsdh_detach(sdhc->sdh);
kfree(sdhc);
}
return -ENODEV;
}
#ifndef BCMLXSDMMC
static
#endif /* BCMLXSDMMC */
int bcmsdh_remove(struct device *dev)
{
bcmsdh_hc_t *sdhc, *prev;
sdhc = sdhcinfo;
drvinfo.detach(sdhc->ch);
bcmsdh_detach(sdhc->sdh);
/* find the SDIO Host Controller state for this pdev
and take it out from the list */
for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
if (sdhc->dev == (void *)dev) {
if (prev)
prev->next = sdhc->next;
else
sdhcinfo = NULL;
break;
}
prev = sdhc;
}
if (!sdhc) {
SDLX_MSG(("%s: failed\n", __func__));
return 0;
}
/* release SDIO Host Controller info */
kfree(sdhc);
#if !defined(BCMLXSDMMC)
dev_set_drvdata(dev, NULL);
#endif /* !defined(BCMLXSDMMC) */
return 0;
}
#endif /* BCMPLATFORM_BUS */
extern int sdio_function_init(void);
int bcmsdh_register(bcmsdh_driver_t *driver)
{
drvinfo = *driver;
SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
return sdio_function_init();
}
extern void sdio_function_cleanup(void);
void bcmsdh_unregister(void)
{
sdio_function_cleanup();
}
#if defined(OOB_INTR_ONLY)
void bcmsdh_oob_intr_set(bool enable)
{
static bool curstate = 1;
unsigned long flags;
spin_lock_irqsave(&sdhcinfo->irq_lock, flags);
if (curstate != enable) {
if (enable)
enable_irq(sdhcinfo->oob_irq);
else
disable_irq_nosync(sdhcinfo->oob_irq);
curstate = enable;
}
spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags);
}
static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
{
dhd_pub_t *dhdp;
dhdp = (dhd_pub_t *) dev_get_drvdata(sdhcinfo->dev);
bcmsdh_oob_intr_set(0);
if (dhdp == NULL) {
SDLX_MSG(("Out of band GPIO interrupt fired way too early\n"));
return IRQ_HANDLED;
}
dhdsdio_isr((void *)dhdp->bus);
return IRQ_HANDLED;
}
int bcmsdh_register_oob_intr(void *dhdp)
{
int error = 0;
SDLX_MSG(("%s Enter\n", __func__));
sdhcinfo->oob_flags =
IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
IORESOURCE_IRQ_SHAREABLE;
dev_set_drvdata(sdhcinfo->dev, dhdp);
if (!sdhcinfo->oob_irq_registered) {
SDLX_MSG(("%s IRQ=%d Type=%X\n", __func__,
(int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags));
/* Refer to customer Host IRQ docs about
proper irqflags definition */
error =
request_irq(sdhcinfo->oob_irq, wlan_oob_irq,
sdhcinfo->oob_flags, "bcmsdh_sdmmc", NULL);
if (error)
return -ENODEV;
irq_set_irq_wake(sdhcinfo->oob_irq, 1);
sdhcinfo->oob_irq_registered = true;
}
return 0;
}
void bcmsdh_unregister_oob_intr(void)
{
SDLX_MSG(("%s: Enter\n", __func__));
irq_set_irq_wake(sdhcinfo->oob_irq, 0);
disable_irq(sdhcinfo->oob_irq); /* just in case.. */
free_irq(sdhcinfo->oob_irq, NULL);
sdhcinfo->oob_irq_registered = false;
}
#endif /* defined(OOB_INTR_ONLY) */
/* Module parameters specific to each host-controller driver */
extern uint sd_msglevel; /* Debug message level */
module_param(sd_msglevel, uint, 0);
extern uint sd_power; /* 0 = SD Power OFF,
1 = SD Power ON. */
module_param(sd_power, uint, 0);
extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF,
1 = SD Clock ON */
module_param(sd_clock, uint, 0);
extern uint sd_divisor; /* Divisor (-1 means external clock) */
module_param(sd_divisor, uint, 0);
extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */
module_param(sd_sdmode, uint, 0);
extern uint sd_hiok; /* Ok to use hi-speed mode */
module_param(sd_hiok, uint, 0);
extern uint sd_f2_blocksize;
module_param(sd_f2_blocksize, int, 0);

File diff suppressed because it is too large Load Diff

View File

@ -1,134 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __BCMSDH_SDMMC_H__
#define __BCMSDH_SDMMC_H__
#ifdef BCMDBG
#define sd_err(x) \
do { \
if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) \
printk x; \
} while (0)
#define sd_trace(x) \
do { \
if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) \
printk x; \
} while (0)
#define sd_info(x) \
do { \
if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) \
printk x; \
} while (0)
#define sd_debug(x) \
do { \
if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) \
printk x; \
} while (0)
#define sd_data(x) \
do { \
if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) \
printk x; \
} while (0)
#define sd_ctrl(x) \
do { \
if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) \
printk x; \
} while (0)
#else
#define sd_err(x)
#define sd_trace(x)
#define sd_info(x)
#define sd_debug(x)
#define sd_data(x)
#define sd_ctrl(x)
#endif
/* Allocate/init/free per-OS private data */
extern int sdioh_sdmmc_osinit(sdioh_info_t *sd);
extern void sdioh_sdmmc_osfree(sdioh_info_t *sd);
#define BLOCK_SIZE_64 64
#define BLOCK_SIZE_512 512
#define BLOCK_SIZE_4318 64
#define BLOCK_SIZE_4328 512
/* internal return code */
#define SUCCESS 0
#define ERROR 1
/* private bus modes */
#define SDIOH_MODE_SD4 2
#define CLIENT_INTR 0x100 /* Get rid of this! */
struct sdioh_info {
struct osl_info *osh; /* osh handler */
bool client_intr_enabled; /* interrupt connnected flag */
bool intr_handler_valid; /* client driver interrupt handler valid */
sdioh_cb_fn_t intr_handler; /* registered interrupt handler */
void *intr_handler_arg; /* argument to call interrupt handler */
u16 intmask; /* Current active interrupts */
void *sdos_info; /* Pointer to per-OS private data */
uint irq; /* Client irq */
int intrcount; /* Client interrupts */
bool sd_use_dma; /* DMA on CMD53 */
bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */
/* Must be on for sd_multiblock to be effective */
bool use_client_ints; /* If this is false, make sure to restore */
int sd_mode; /* SD1/SD4/SPI */
int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
u8 num_funcs; /* Supported funcs on client */
u32 com_cis_ptr;
u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
uint max_dma_len;
uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */
/* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */
};
/************************************************************
* Internal interfaces: per-port references into bcmsdh_sdmmc.c
*/
/* Global message bits */
extern uint sd_msglevel;
/* OS-independent interrupt handler */
extern bool check_client_intr(sdioh_info_t *sd);
/* Core interrupt enable/disable of device interrupts */
extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
/**************************************************************
* Internal interfaces: bcmsdh_sdmmc.c references to per-port code
*/
/* Register mapping routines */
extern u32 *sdioh_sdmmc_reg_map(s32 addr, int size);
extern void sdioh_sdmmc_reg_unmap(s32 addr, int size);
/* Interrupt (de)registration routines */
extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq);
extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd);
typedef struct _BCMSDH_SDMMC_INSTANCE {
sdioh_info_t *sd;
struct sdio_func *func[SDIOD_MAX_IOFUNCS];
u32 host_claimed;
} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE;
#endif /* __BCMSDH_SDMMC_H__ */

View File

@ -1,235 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/types.h>
#include <linux/sched.h> /* request_irq() */
#include <linux/netdevice.h>
#include <bcmdefs.h>
#include <bcmutils.h>
#include <sdio.h> /* SDIO Specs */
#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
#include <sdiovar.h> /* to get msglevel bit values */
#include <linux/mmc/core.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include "dngl_stats.h"
#include "dhd.h"
#if !defined(SDIO_VENDOR_ID_BROADCOM)
#define SDIO_VENDOR_ID_BROADCOM 0x02d0
#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */
#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000
#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)
#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */
#if !defined(SDIO_DEVICE_ID_BROADCOM_4325)
#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
#if !defined(SDIO_DEVICE_ID_BROADCOM_4329)
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
#if !defined(SDIO_DEVICE_ID_BROADCOM_4319)
#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319
#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
#include <bcmsdh_sdmmc.h>
#include <dhd_dbg.h>
#include <wl_cfg80211.h>
extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
int sdio_function_init(void);
void sdio_function_cleanup(void);
/* module param defaults */
static int clockoverride;
module_param(clockoverride, int, 0644);
MODULE_PARM_DESC(clockoverride, "SDIO card clock override");
PBCMSDH_SDMMC_INSTANCE gInstance;
/* Maximum number of bcmsdh_sdmmc devices supported by driver */
#define BCMSDH_SDMMC_MAX_DEVICES 1
extern int bcmsdh_probe(struct device *dev);
extern int bcmsdh_remove(struct device *dev);
struct device sdmmc_dev;
static int bcmsdh_sdmmc_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
int ret = 0;
static struct sdio_func sdio_func_0;
sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
sd_trace(("sdio_bcmsdh: func->class=%x\n", func->class));
sd_trace(("sdio_vendor: 0x%04x\n", func->vendor));
sd_trace(("sdio_device: 0x%04x\n", func->device));
sd_trace(("Function#: 0x%04x\n", func->num));
if (func->num == 1) {
sdio_func_0.num = 0;
sdio_func_0.card = func->card;
gInstance->func[0] = &sdio_func_0;
if (func->device == 0x4) { /* 4318 */
gInstance->func[2] = NULL;
sd_trace(("NIC found, calling bcmsdh_probe...\n"));
ret = bcmsdh_probe(&sdmmc_dev);
}
}
gInstance->func[func->num] = func;
if (func->num == 2) {
wl_cfg80211_sdio_func(func);
sd_trace(("F2 found, calling bcmsdh_probe...\n"));
ret = bcmsdh_probe(&sdmmc_dev);
}
return ret;
}
static void bcmsdh_sdmmc_remove(struct sdio_func *func)
{
sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
sd_info(("sdio_bcmsdh: func->class=%x\n", func->class));
sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
sd_info(("sdio_device: 0x%04x\n", func->device));
sd_info(("Function#: 0x%04x\n", func->num));
if (func->num == 2) {
sd_trace(("F2 found, calling bcmsdh_remove...\n"));
bcmsdh_remove(&sdmmc_dev);
}
}
/* devices we support, null terminated */
static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT)},
{SDIO_DEVICE
(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)},
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325)},
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319)},
{ /* end: all zeroes */ },
};
MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
static struct sdio_driver bcmsdh_sdmmc_driver = {
.probe = bcmsdh_sdmmc_probe,
.remove = bcmsdh_sdmmc_remove,
.name = "brcmfmac",
.id_table = bcmsdh_sdmmc_ids,
};
struct sdos_info {
sdioh_info_t *sd;
spinlock_t lock;
};
int sdioh_sdmmc_osinit(sdioh_info_t *sd)
{
struct sdos_info *sdos;
sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC);
sd->sdos_info = (void *)sdos;
if (sdos == NULL)
return -ENOMEM;
sdos->sd = sd;
spin_lock_init(&sdos->lock);
return 0;
}
void sdioh_sdmmc_osfree(sdioh_info_t *sd)
{
struct sdos_info *sdos;
ASSERT(sd && sd->sdos_info);
sdos = (struct sdos_info *)sd->sdos_info;
kfree(sdos);
}
/* Interrupt enable/disable */
SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *sd, bool enable)
{
unsigned long flags;
struct sdos_info *sdos;
sd_trace(("%s: %s\n", __func__, enable ? "Enabling" : "Disabling"));
sdos = (struct sdos_info *)sd->sdos_info;
ASSERT(sdos);
#if !defined(OOB_INTR_ONLY)
if (enable && !(sd->intr_handler && sd->intr_handler_arg)) {
sd_err(("%s: no handler registered, will not enable\n",
__func__));
return SDIOH_API_RC_FAIL;
}
#endif /* !defined(OOB_INTR_ONLY) */
/* Ensure atomicity for enable/disable calls */
spin_lock_irqsave(&sdos->lock, flags);
sd->client_intr_enabled = enable;
if (enable)
sdioh_sdmmc_devintr_on(sd);
else
sdioh_sdmmc_devintr_off(sd);
spin_unlock_irqrestore(&sdos->lock, flags);
return SDIOH_API_RC_SUCCESS;
}
/*
* module init
*/
int sdio_function_init(void)
{
int error = 0;
sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL);
if (!gInstance)
return -ENOMEM;
memset(&sdmmc_dev, 0, sizeof(sdmmc_dev));
error = sdio_register_driver(&bcmsdh_sdmmc_driver);
return error;
}
/*
* module cleanup
*/
extern int bcmsdh_remove(struct device *dev);
void sdio_function_cleanup(void)
{
sd_trace(("%s Enter\n", __func__));
sdio_unregister_driver(&bcmsdh_sdmmc_driver);
kfree(gInstance);
}

File diff suppressed because it is too large Load Diff

View File

@ -14,69 +14,65 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _dhd_bus_h_
#define _dhd_bus_h_
#ifndef _BRCMF_BUS_H_
#define _BRCMF_BUS_H_
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef BRCMF_SDALIGN
#define BRCMF_SDALIGN 32
#endif
#if !ISPOWEROF2(BRCMF_SDALIGN)
#error BRCMF_SDALIGN is not a power of 2!
#endif
/*
* Exported from dhd bus module (dhd_usb, dhd_sdio)
* Exported from brcmf bus module (brcmf_usb, brcmf_sdio)
*/
/* Indicate (dis)interest in finding dongles. */
extern int dhd_bus_register(void);
extern void dhd_bus_unregister(void);
/* dongle ram module parameter */
extern int brcmf_dongle_memsize;
/* Download firmware image and nvram image */
extern bool dhd_bus_download_firmware(struct dhd_bus *bus,
char *fw_path, char *nv_path);
/* Tx/Rx bounds module parameters */
extern uint brcmf_txbound;
extern uint brcmf_rxbound;
/* Watchdog timer interval */
extern uint brcmf_watchdog_ms;
/* Indicate (dis)interest in finding dongles. */
extern int brcmf_bus_register(void);
extern void brcmf_bus_unregister(void);
/* Stop bus module: clear pending frames, disable data flow */
extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex);
extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex);
/* Initialize bus module: prepare for communication w/dongle */
extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex);
extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex);
/* Send a data frame to the dongle. Callee disposes of txp. */
extern int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *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 dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen);
extern int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen);
extern int
brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
/* Watchdog timer function */
extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
#ifdef DHD_DEBUG
/* Device console input function */
extern int dhd_bus_console_in(dhd_pub_t *dhd, unsigned char *msg, uint msglen);
#endif /* DHD_DEBUG */
/* Deferred processing for the bus, return true requests reschedule */
extern bool dhd_bus_dpc(struct dhd_bus *bus);
extern void dhd_bus_isr(bool *InterruptRecognized,
bool *QueueMiniportHandleInterrupt, void *arg);
extern int
brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
/* Check for and handle local prot-specific iovar commands */
extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
extern int brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name,
void *params, int plen, void *arg, int len,
bool set);
/* Add bus dump output to a buffer */
extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
extern void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr,
struct brcmu_strbuf *strbuf);
/* Clear any bus counters */
extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
extern void brcmf_bus_clearcounts(struct brcmf_pub *drvr);
/* return the dongle chipid */
extern uint dhd_bus_chip(struct dhd_bus *bus);
extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick);
/* Set user-specified nvram parameters. */
extern void dhd_bus_set_nvram_params(struct dhd_bus *bus,
const char *nvram_params);
extern void *dhd_bus_pub(struct dhd_bus *bus);
extern void *dhd_bus_txq(struct dhd_bus *bus);
extern uint dhd_bus_hdrlen(struct dhd_bus *bus);
#endif /* _dhd_bus_h_ */
#endif /* _BRCMF_BUS_H_ */

View File

@ -16,33 +16,71 @@
#include <linux/types.h>
#include <linux/netdevice.h>
#include <bcmdefs.h>
#include <linux/sched.h>
#include <defs.h>
#include <bcmutils.h>
#include <bcmcdc.h>
#include <brcmu_utils.h>
#include <brcmu_wifi.h>
#include <dngl_stats.h>
#include <dhd.h>
#include <dhd_proto.h>
#include <dhd_bus.h>
#include <dhd_dbg.h>
#ifdef CUSTOMER_HW2
int wifi_get_mac_addr(unsigned char *buf);
#endif
#include "dhd.h"
#include "dhd_proto.h"
#include "dhd_bus.h"
#include "dhd_dbg.h"
extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
struct brcmf_proto_cdc_ioctl {
u32 cmd; /* ioctl command value */
u32 len; /* lower 16: output buflen;
* upper 16: input buflen (excludes header) */
u32 flags; /* flag defns given below */
u32 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 CDCF_IOC_ERROR 0x01 /* 1=ioctl cmd failed */
#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */
#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */
#define CDCF_IOC_IF_SHIFT 12
#define CDCF_IOC_ID_MASK 0xFFFF0000 /* id an ioctl pairing */
#define CDCF_IOC_ID_SHIFT 16 /* ID Mask shift bits */
#define CDC_IOC_ID(flags) \
(((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
#define CDC_SET_IF_IDX(hdr, idx) \
((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \
((idx) << CDCF_IOC_IF_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;
};
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef DHD_SDALIGN
#define DHD_SDALIGN 32
#endif
#if !ISPOWEROF2(DHD_SDALIGN)
#error DHD_SDALIGN is not a power of 2!
#endif
#define RETRIES 2 /* # of retries to retrieve matching ioctl response */
#define BUS_HEADER_LEN (16+DHD_SDALIGN) /* Must be atleast SDPCM_RESERVE
* defined in dhd_sdio.c
#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.
@ -51,21 +89,22 @@ extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
* round off at the end of buffer
*/
typedef struct dhd_prot {
struct brcmf_proto {
u16 reqid;
u8 pending;
u32 lastcmd;
u8 bus_header[BUS_HEADER_LEN];
cdc_ioctl_t msg;
unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN];
} dhd_prot_t;
struct brcmf_proto_cdc_ioctl msg;
unsigned char buf[BRCMF_C_IOCTL_MAXLEN + ROUND_UP_MARGIN];
};
static int dhdcdc_msg(dhd_pub_t *dhd)
static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
{
dhd_prot_t *prot = dhd->prot;
int len = le32_to_cpu(prot->msg.len) + sizeof(cdc_ioctl_t);
struct brcmf_proto *prot = drvr->prot;
int len = le32_to_cpu(prot->msg.len) +
sizeof(struct brcmf_proto_cdc_ioctl);
DHD_TRACE(("%s: Enter\n", __func__));
BRCMF_TRACE(("%s: Enter\n", __func__));
/* 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
@ -75,20 +114,21 @@ static int dhdcdc_msg(dhd_pub_t *dhd)
len = CDC_MAX_MSG_SIZE;
/* Send request */
return dhd_bus_txctl(dhd->bus, (unsigned char *)&prot->msg, len);
return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg,
len);
}
static int dhdcdc_cmplt(dhd_pub_t *dhd, u32 id, u32 len)
static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
{
int ret;
dhd_prot_t *prot = dhd->prot;
struct brcmf_proto *prot = drvr->prot;
DHD_TRACE(("%s: Enter\n", __func__));
BRCMF_TRACE(("%s: Enter\n", __func__));
do {
ret =
dhd_bus_rxctl(dhd->bus, (unsigned char *)&prot->msg,
len + sizeof(cdc_ioctl_t));
ret = brcmf_sdbrcm_bus_rxctl(drvr->bus,
(unsigned char *)&prot->msg,
len + sizeof(struct brcmf_proto_cdc_ioctl));
if (ret < 0)
break;
} while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id);
@ -97,30 +137,31 @@ static int dhdcdc_cmplt(dhd_pub_t *dhd, u32 id, u32 len)
}
int
dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd,
void *buf, uint len)
{
dhd_prot_t *prot = dhd->prot;
cdc_ioctl_t *msg = &prot->msg;
struct brcmf_proto *prot = drvr->prot;
struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
void *info;
int ret = 0, retries = 0;
u32 id, flags = 0;
DHD_TRACE(("%s: Enter\n", __func__));
DHD_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
BRCMF_TRACE(("%s: Enter\n", __func__));
BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
/* Respond "bcmerror" and "bcmerrorstr" with local cache */
if (cmd == WLC_GET_VAR && buf) {
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 = dhd->dongle_error;
*(int *)buf = drvr->dongle_error;
goto done;
}
}
memset(msg, 0, sizeof(cdc_ioctl_t));
memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl));
msg->cmd = cpu_to_le32(cmd);
msg->len = cpu_to_le32(len);
@ -131,16 +172,16 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
if (buf)
memcpy(prot->buf, buf, len);
ret = dhdcdc_msg(dhd);
ret = brcmf_proto_cdc_msg(drvr);
if (ret < 0) {
DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status "
"%d\n", ret));
BRCMF_ERROR(("brcmf_proto_cdc_query_ioctl: brcmf_proto_cdc_msg "
"failed w/status %d\n", ret));
goto done;
}
retry:
/* wait for interrupt and get first fragment */
ret = dhdcdc_cmplt(dhd, prot->reqid, len);
ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
if (ret < 0)
goto done;
@ -150,8 +191,9 @@ retry:
if ((id < prot->reqid) && (++retries < RETRIES))
goto retry;
if (id != prot->reqid) {
DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
dhd_ifname(dhd, ifidx), __func__, id, prot->reqid));
BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
brcmf_ifname(drvr, ifidx), __func__, id,
prot->reqid));
ret = -EINVAL;
goto done;
}
@ -170,24 +212,25 @@ retry:
if (flags & CDCF_IOC_ERROR) {
ret = le32_to_cpu(msg->status);
/* Cache error from dongle */
dhd->dongle_error = ret;
drvr->dongle_error = ret;
}
done:
return ret;
}
int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd,
void *buf, uint len)
{
dhd_prot_t *prot = dhd->prot;
cdc_ioctl_t *msg = &prot->msg;
struct brcmf_proto *prot = drvr->prot;
struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
int ret = 0;
u32 flags, id;
DHD_TRACE(("%s: Enter\n", __func__));
DHD_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
BRCMF_TRACE(("%s: Enter\n", __func__));
BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
memset(msg, 0, sizeof(cdc_ioctl_t));
memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl));
msg->cmd = cpu_to_le32(cmd);
msg->len = cpu_to_le32(len);
@ -198,11 +241,11 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
if (buf)
memcpy(prot->buf, buf, len);
ret = dhdcdc_msg(dhd);
ret = brcmf_proto_cdc_msg(drvr);
if (ret < 0)
goto done;
ret = dhdcdc_cmplt(dhd, prot->reqid, len);
ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
if (ret < 0)
goto done;
@ -210,8 +253,9 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
if (id != prot->reqid) {
DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
dhd_ifname(dhd, ifidx), __func__, id, prot->reqid));
BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
brcmf_ifname(drvr, ifidx), __func__, id,
prot->reqid));
ret = -EINVAL;
goto done;
}
@ -220,41 +264,40 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
if (flags & CDCF_IOC_ERROR) {
ret = le32_to_cpu(msg->status);
/* Cache error from dongle */
dhd->dongle_error = ret;
drvr->dongle_error = ret;
}
done:
return ret;
}
extern int dhd_bus_interface(struct dhd_bus *bus, uint arg, void *arg2);
int
dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len)
brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, struct brcmf_ioctl *ioc,
void *buf, int len)
{
dhd_prot_t *prot = dhd->prot;
struct brcmf_proto *prot = drvr->prot;
int ret = -1;
if (dhd->busstate == DHD_BUS_DOWN) {
DHD_ERROR(("%s : bus is down. we have nothing to do\n",
__func__));
if (drvr->busstate == BRCMF_BUS_DOWN) {
BRCMF_ERROR(("%s : bus is down. we have nothing to do\n",
__func__));
return ret;
}
dhd_os_proto_block(dhd);
brcmf_os_proto_block(drvr);
DHD_TRACE(("%s: Enter\n", __func__));
BRCMF_TRACE(("%s: Enter\n", __func__));
ASSERT(len <= WLC_IOCTL_MAXLEN);
if (len > WLC_IOCTL_MAXLEN)
if (len > BRCMF_C_IOCTL_MAXLEN)
goto done;
if (prot->pending == true) {
DHD_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) "
"lastcmd=0x%x (%lu)\n",
ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
(unsigned long)prot->lastcmd));
if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR))
DHD_TRACE(("iovar cmd=%s\n", (char *)buf));
BRCMF_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) "
"lastcmd=0x%x (%lu)\n",
ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
(unsigned long)prot->lastcmd));
if ((ioc->cmd == BRCMF_C_SET_VAR) ||
(ioc->cmd == BRCMF_C_GET_VAR))
BRCMF_TRACE(("iovar cmd=%s\n", (char *)buf));
goto done;
}
@ -262,36 +305,39 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len)
prot->pending = true;
prot->lastcmd = ioc->cmd;
if (ioc->set)
ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len);
ret = brcmf_proto_cdc_set_ioctl(drvr, ifidx, ioc->cmd,
buf, len);
else {
ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len);
ret = brcmf_proto_cdc_query_ioctl(drvr, ifidx, ioc->cmd,
buf, len);
if (ret > 0)
ioc->used = ret - sizeof(cdc_ioctl_t);
ioc->used = ret - sizeof(struct brcmf_proto_cdc_ioctl);
}
/* Too many programs assume ioctl() returns 0 on success */
if (ret >= 0)
ret = 0;
else {
cdc_ioctl_t *msg = &prot->msg;
struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
/* len == needed when set/query fails from dongle */
ioc->needed = le32_to_cpu(msg->len);
}
/* Intercept the wme_dp ioctl here */
if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) {
if (!ret && ioc->cmd == BRCMF_C_SET_VAR &&
!strcmp(buf, "wme_dp")) {
int slen, val = 0;
slen = strlen("wme_dp") + 1;
if (len >= (int)(slen + sizeof(int)))
memcpy(&val, (char *)buf + slen, sizeof(int));
dhd->wme_dp = (u8) le32_to_cpu(val);
drvr->wme_dp = (u8) le32_to_cpu(val);
}
prot->pending = false;
done:
dhd_os_proto_unblock(dhd);
brcmf_os_proto_unblock(drvr);
return ret;
}
@ -302,35 +348,23 @@ done:
(((struct sk_buff *)(skb))->ip_summed = \
((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because
skb->ip_summed is overloaded */
int
dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
void *params, int plen, void *arg, int len, bool set)
void brcmf_proto_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf)
{
return -ENOTSUPP;
brcmu_bprintf(strbuf, "Protocol CDC: reqid %d\n", drvr->prot->reqid);
}
void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
struct sk_buff *pktbuf)
{
bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid);
}
struct brcmf_proto_bdc_header *h;
void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf)
{
#ifdef BDC
struct bdc_header *h;
#endif /* BDC */
BRCMF_TRACE(("%s: Enter\n", __func__));
DHD_TRACE(("%s: Enter\n", __func__));
#ifdef BDC
/* Push BDC header used to convey priority for buses that don't */
skb_push(pktbuf, BDC_HEADER_LEN);
h = (struct bdc_header *)(pktbuf->data);
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
if (PKTSUMNEEDED(pktbuf))
@ -339,79 +373,74 @@ void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf)
h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
h->flags2 = 0;
h->rssi = 0;
#endif /* BDC */
BDC_SET_IF_IDX(h, ifidx);
}
int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf)
int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx,
struct sk_buff *pktbuf)
{
#ifdef BDC
struct bdc_header *h;
#endif
struct brcmf_proto_bdc_header *h;
DHD_TRACE(("%s: Enter\n", __func__));
BRCMF_TRACE(("%s: Enter\n", __func__));
#ifdef BDC
/* Pop BDC header used to convey priority for buses that don't */
if (pktbuf->len < BDC_HEADER_LEN) {
DHD_ERROR(("%s: rx data too short (%d < %d)\n", __func__,
pktbuf->len, BDC_HEADER_LEN));
BRCMF_ERROR(("%s: rx data too short (%d < %d)\n", __func__,
pktbuf->len, BDC_HEADER_LEN));
return -EBADE;
}
h = (struct bdc_header *)(pktbuf->data);
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
*ifidx = BDC_GET_IF_IDX(h);
if (*ifidx >= DHD_MAX_IFS) {
DHD_ERROR(("%s: rx data ifnum out of range (%d)\n",
__func__, *ifidx));
if (*ifidx >= BRCMF_MAX_IFS) {
BRCMF_ERROR(("%s: rx data ifnum out of range (%d)\n",
__func__, *ifidx));
return -EBADE;
}
if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
BDC_PROTO_VER) {
DHD_ERROR(("%s: non-BDC packet received, flags 0x%x\n",
dhd_ifname(dhd, *ifidx), h->flags));
BRCMF_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) {
DHD_INFO(("%s: BDC packet received with good rx-csum, "
"flags 0x%x\n",
dhd_ifname(dhd, *ifidx), h->flags));
BRCMF_INFO(("%s: BDC packet received with good rx-csum, "
"flags 0x%x\n",
brcmf_ifname(drvr, *ifidx), h->flags));
PKTSETSUMGOOD(pktbuf, true);
}
pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
skb_pull(pktbuf, BDC_HEADER_LEN);
#endif /* BDC */
return 0;
}
int dhd_prot_attach(dhd_pub_t *dhd)
int brcmf_proto_attach(struct brcmf_pub *drvr)
{
dhd_prot_t *cdc;
struct brcmf_proto *cdc;
cdc = kzalloc(sizeof(dhd_prot_t), GFP_ATOMIC);
cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
if (!cdc) {
DHD_ERROR(("%s: kmalloc failed\n", __func__));
BRCMF_ERROR(("%s: kmalloc failed\n", __func__));
goto fail;
}
/* ensure that the msg buf directly follows the cdc msg struct */
if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
DHD_ERROR(("dhd_prot_t is not correctly defined\n"));
BRCMF_ERROR(("struct brcmf_proto is not correctly defined\n"));
goto fail;
}
dhd->prot = cdc;
#ifdef BDC
dhd->hdrlen += BDC_HEADER_LEN;
#endif
dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN;
drvr->prot = cdc;
drvr->hdrlen += BDC_HEADER_LEN;
drvr->maxctl = BRCMF_C_IOCTL_MAXLEN +
sizeof(struct brcmf_proto_cdc_ioctl) + ROUND_UP_MARGIN;
return 0;
fail:
@ -420,55 +449,54 @@ fail:
}
/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
void dhd_prot_detach(dhd_pub_t *dhd)
void brcmf_proto_detach(struct brcmf_pub *drvr)
{
kfree(dhd->prot);
dhd->prot = NULL;
kfree(drvr->prot);
drvr->prot = NULL;
}
void dhd_prot_dstats(dhd_pub_t *dhd)
void brcmf_proto_dstats(struct brcmf_pub *drvr)
{
/* No stats from dongle added yet, copy bus stats */
dhd->dstats.tx_packets = dhd->tx_packets;
dhd->dstats.tx_errors = dhd->tx_errors;
dhd->dstats.rx_packets = dhd->rx_packets;
dhd->dstats.rx_errors = dhd->rx_errors;
dhd->dstats.rx_dropped = dhd->rx_dropped;
dhd->dstats.multicast = dhd->rx_multicast;
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 dhd_prot_init(dhd_pub_t *dhd)
int brcmf_proto_init(struct brcmf_pub *drvr)
{
int ret = 0;
char buf[128];
DHD_TRACE(("%s: Enter\n", __func__));
BRCMF_TRACE(("%s: Enter\n", __func__));
dhd_os_proto_block(dhd);
brcmf_os_proto_block(drvr);
/* Get the device MAC address */
strcpy(buf, "cur_etheraddr");
ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf));
ret = brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR,
buf, sizeof(buf));
if (ret < 0) {
dhd_os_proto_unblock(dhd);
brcmf_os_proto_unblock(drvr);
return ret;
}
memcpy(dhd->mac, buf, ETH_ALEN);
memcpy(drvr->mac, buf, ETH_ALEN);
dhd_os_proto_unblock(dhd);
brcmf_os_proto_unblock(drvr);
#ifdef EMBEDDED_PLATFORM
ret = dhd_preinit_ioctls(dhd);
#endif /* EMBEDDED_PLATFORM */
ret = brcmf_c_preinit_ioctls(drvr);
/* Always assumes wl for now */
dhd->iswl = true;
drvr->iswl = true;
return ret;
}
void dhd_prot_stop(dhd_pub_t *dhd)
void brcmf_proto_stop(struct brcmf_pub *drvr)
{
/* Nothing to do for CDC */
}

File diff suppressed because it is too large Load Diff

View File

@ -1,158 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/netdevice.h>
#include <bcmutils.h>
#include <dngl_stats.h>
#include <dhd.h>
#include <wlioctl.h>
#include <wl_iw.h>
#define WL_ERROR(fmt, args...) printk(fmt, ##args)
#define WL_TRACE(fmt, args...) no_printk(fmt, ##args)
#ifdef CUSTOMER_HW
extern void bcm_wlan_power_off(int);
extern void bcm_wlan_power_on(int);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
int wifi_set_carddetect(int on);
int wifi_set_power(int on, unsigned long msec);
int wifi_get_irq_number(unsigned long *irq_flags_ptr);
#endif
#if defined(OOB_INTR_ONLY)
#if defined(BCMLXSDMMC)
extern int sdioh_mmc_irq(int irq);
#endif /* (BCMLXSDMMC) */
#ifdef CUSTOMER_HW3
#include <mach/gpio.h>
#endif
/* Customer specific Host GPIO definition */
static int dhd_oob_gpio_num = -1; /* GG 19 */
module_param(dhd_oob_gpio_num, int, 0644);
MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number");
int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
{
int host_oob_irq = 0;
#ifdef CUSTOMER_HW2
host_oob_irq = wifi_get_irq_number(irq_flags_ptr);
#else /* for NOT CUSTOMER_HW2 */
#if defined(CUSTOM_OOB_GPIO_NUM)
if (dhd_oob_gpio_num < 0)
dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
#endif
if (dhd_oob_gpio_num < 0) {
WL_ERROR("%s: ERROR customer specific Host GPIO is NOT defined\n",
__func__);
return dhd_oob_gpio_num;
}
WL_ERROR("%s: customer specific Host GPIO number is (%d)\n",
__func__, dhd_oob_gpio_num);
#if defined CUSTOMER_HW
host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num);
#elif defined CUSTOMER_HW3
gpio_request(dhd_oob_gpio_num, "oob irq");
host_oob_irq = gpio_to_irq(dhd_oob_gpio_num);
gpio_direction_input(dhd_oob_gpio_num);
#endif /* CUSTOMER_HW */
#endif /* CUSTOMER_HW2 */
return host_oob_irq;
}
#endif /* defined(OOB_INTR_ONLY) */
/* Customer function to control hw specific wlan gpios */
void dhd_customer_gpio_wlan_ctrl(int onoff)
{
switch (onoff) {
case WLAN_RESET_OFF:
WL_TRACE("%s: call customer specific GPIO to insert WLAN RESET\n",
__func__);
#ifdef CUSTOMER_HW
bcm_wlan_power_off(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
wifi_set_power(0, 0);
#endif
WL_ERROR("=========== WLAN placed in RESET ========\n");
break;
case WLAN_RESET_ON:
WL_TRACE("%s: callc customer specific GPIO to remove WLAN RESET\n",
__func__);
#ifdef CUSTOMER_HW
bcm_wlan_power_on(2);
#endif /* CUSTOMER_HW */
#ifdef CUSTOMER_HW2
wifi_set_power(1, 0);
#endif
WL_ERROR("=========== WLAN going back to live ========\n");
break;
case WLAN_POWER_OFF:
WL_TRACE("%s: call customer specific GPIO to turn off WL_REG_ON\n",
__func__);
#ifdef CUSTOMER_HW
bcm_wlan_power_off(1);
#endif /* CUSTOMER_HW */
break;
case WLAN_POWER_ON:
WL_TRACE("%s: call customer specific GPIO to turn on WL_REG_ON\n",
__func__);
#ifdef CUSTOMER_HW
bcm_wlan_power_on(1);
#endif /* CUSTOMER_HW */
/* Lets customer power to get stable */
udelay(200);
break;
}
}
#ifdef GET_CUSTOM_MAC_ENABLE
/* Function to get custom MAC address */
int dhd_custom_get_mac_address(unsigned char *buf)
{
WL_TRACE("%s Enter\n", __func__);
if (!buf)
return -EINVAL;
/* Customer access to MAC address stored outside of DHD driver */
#ifdef EXAMPLE_GET_MAC
/* EXAMPLE code */
{
u8 ea_example[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xFF};
memcpy(buf, ea_example, ETH_ALEN);
}
#endif /* EXAMPLE_GET_MAC */
return 0;
}
#endif /* GET_CUSTOM_MAC_ENABLE */

View File

@ -14,90 +14,57 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _dhd_dbg_
#define _dhd_dbg_
#ifndef _BRCMF_DBG_H_
#define _BRCMF_DBG_H_
#if defined(DHD_DEBUG)
#if defined(BCMDBG)
#define DHD_ERROR(args) \
do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
#define BRCMF_ERROR(args) \
do {if ((brcmf_msg_level & BRCMF_ERROR_VAL) && (net_ratelimit())) \
printk args; } while (0)
#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) \
#define BRCMF_TRACE(args) do {if (brcmf_msg_level & BRCMF_TRACE_VAL) \
printk args; } while (0)
#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) \
#define BRCMF_INFO(args) do {if (brcmf_msg_level & BRCMF_INFO_VAL) \
printk args; } while (0)
#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) \
#define BRCMF_DATA(args) do {if (brcmf_msg_level & BRCMF_DATA_VAL) \
printk args; } while (0)
#define DHD_CTL(args) do {if (dhd_msg_level & DHD_CTL_VAL) \
#define BRCMF_CTL(args) do {if (brcmf_msg_level & BRCMF_CTL_VAL) \
printk args; } while (0)
#define DHD_TIMER(args) do {if (dhd_msg_level & DHD_TIMER_VAL) \
#define BRCMF_TIMER(args) do {if (brcmf_msg_level & BRCMF_TIMER_VAL) \
printk args; } while (0)
#define DHD_HDRS(args) do {if (dhd_msg_level & DHD_HDRS_VAL) \
#define BRCMF_INTR(args) do {if (brcmf_msg_level & BRCMF_INTR_VAL) \
printk args; } while (0)
#define DHD_BYTES(args) do {if (dhd_msg_level & DHD_BYTES_VAL) \
#define BRCMF_GLOM(args) do {if (brcmf_msg_level & BRCMF_GLOM_VAL) \
printk args; } while (0)
#define DHD_INTR(args) do {if (dhd_msg_level & DHD_INTR_VAL) \
printk args; } while (0)
#define DHD_GLOM(args) do {if (dhd_msg_level & DHD_GLOM_VAL) \
printk args; } while (0)
#define DHD_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) \
printk args; } while (0)
#define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) \
printk args; } while (0)
#define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) \
#define BRCMF_EVENT(args) do {if (brcmf_msg_level & BRCMF_EVENT_VAL) \
printk args; } while (0)
#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL)
#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL)
#define DHD_INFO_ON() (dhd_msg_level & DHD_INFO_VAL)
#define DHD_DATA_ON() (dhd_msg_level & DHD_DATA_VAL)
#define DHD_CTL_ON() (dhd_msg_level & DHD_CTL_VAL)
#define DHD_TIMER_ON() (dhd_msg_level & DHD_TIMER_VAL)
#define DHD_HDRS_ON() (dhd_msg_level & DHD_HDRS_VAL)
#define DHD_BYTES_ON() (dhd_msg_level & DHD_BYTES_VAL)
#define DHD_INTR_ON() (dhd_msg_level & DHD_INTR_VAL)
#define DHD_GLOM_ON() (dhd_msg_level & DHD_GLOM_VAL)
#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL)
#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL)
#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL)
#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 DHD_DEBUG) */
#else /* (defined BCMDBG) || (defined BCMDBG) */
#define DHD_ERROR(args) do {if (net_ratelimit()) printk args; } while (0)
#define DHD_TRACE(args)
#define DHD_INFO(args)
#define DHD_DATA(args)
#define DHD_CTL(args)
#define DHD_TIMER(args)
#define DHD_HDRS(args)
#define DHD_BYTES(args)
#define DHD_INTR(args)
#define DHD_GLOM(args)
#define DHD_EVENT(args)
#define DHD_BTA(args)
#define DHD_ISCAN(args)
#define BRCMF_ERROR(args) do {if (net_ratelimit()) printk args; } while (0)
#define BRCMF_TRACE(args)
#define BRCMF_INFO(args)
#define BRCMF_DATA(args)
#define BRCMF_CTL(args)
#define BRCMF_TIMER(args)
#define BRCMF_INTR(args)
#define BRCMF_GLOM(args)
#define BRCMF_EVENT(args)
#define DHD_ERROR_ON() 0
#define DHD_TRACE_ON() 0
#define DHD_INFO_ON() 0
#define DHD_DATA_ON() 0
#define DHD_CTL_ON() 0
#define DHD_TIMER_ON() 0
#define DHD_HDRS_ON() 0
#define DHD_BYTES_ON() 0
#define DHD_INTR_ON() 0
#define DHD_GLOM_ON() 0
#define DHD_EVENT_ON() 0
#define DHD_BTA_ON() 0
#define DHD_ISCAN_ON() 0
#endif /* defined(DHD_DEBUG) */
#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
#define DHD_LOG(args)
#endif /* defined(BCMDBG) */
#define DHD_NONE(args)
extern int dhd_msg_level;
extern int brcmf_msg_level;
/* Defines msg bits */
#include <dhdioctl.h>
#endif /* _dhd_dbg_ */
#endif /* _BRCMF_DBG_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
int setScheduler(struct task_struct *p, int policy, struct sched_param *param)
{
int rc = 0;
rc = sched_setscheduler(p, policy, param);
return rc;
}

View File

@ -14,11 +14,8 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _dhd_proto_h_
#define _dhd_proto_h_
#include <dhdioctl.h>
#include <wlioctl.h>
#ifndef _BRCMF_PROTO_H_
#define _BRCMF_PROTO_H_
#ifndef IOCTL_RESP_TIMEOUT
#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */
@ -29,62 +26,50 @@
#endif
/*
* Exported from the dhd protocol module (dhd_cdc, dhd_rndis)
* Exported from the brcmf protocol module (brcmf_cdc)
*/
/* Linkage, sets prot link and updates hdrlen in pub */
extern int dhd_prot_attach(dhd_pub_t *dhdp);
extern int brcmf_proto_attach(struct brcmf_pub *drvr);
/* Unlink, frees allocated protocol memory (including dhd_prot) */
extern void dhd_prot_detach(dhd_pub_t *dhdp);
/* 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 dhd_prot_init(dhd_pub_t *dhdp);
extern int brcmf_proto_init(struct brcmf_pub *drvr);
/* Stop protocol: sync w/dongle state. */
extern void dhd_prot_stop(dhd_pub_t *dhdp);
extern void brcmf_proto_stop(struct brcmf_pub *drvr);
/* Add any protocol-specific data header.
* Caller must reserve prot_hdrlen prepend space.
*/
extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, struct sk_buff *txp);
extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
struct sk_buff *txp);
/* Remove any protocol-specific data header. */
extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, struct sk_buff *rxp);
extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx,
struct sk_buff *rxp);
/* Use protocol to issue ioctl to dongle */
extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc,
void *buf, int len);
/* Check for and handle local prot-specific iovar commands */
extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
void *params, int plen, void *arg, int len,
bool set);
extern int brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx,
struct brcmf_ioctl *ioc, void *buf, int len);
/* Add prot dump output to a buffer */
extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
extern void brcmf_proto_dump(struct brcmf_pub *drvr,
struct brcmu_strbuf *strbuf);
/* Update local copy of dongle statistics */
extern void dhd_prot_dstats(dhd_pub_t *dhdp);
extern void brcmf_proto_dstats(struct brcmf_pub *drvr);
extern int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf,
uint buflen);
extern int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc,
void *buf, uint buflen);
extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
extern int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr);
/********************************
* For version-string expansion *
*/
#if defined(BDC)
#define DHD_PROTOCOL "bdc"
#elif defined(CDC)
#define DHD_PROTOCOL "cdc"
#elif defined(RNDIS)
#define DHD_PROTOCOL "rndis"
#else
#define DHD_PROTOCOL "unknown"
#endif /* proto */
extern int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx,
uint cmd, void *buf, uint len);
#endif /* _dhd_proto_h_ */
#endif /* _BRCMF_PROTO_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,100 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _dhdioctl_h_
#define _dhdioctl_h_
/* Linux network driver ioctl encoding */
typedef struct dhd_ioctl {
uint cmd; /* common ioctl definition */
void *buf; /* pointer to user buffer */
uint len; /* length of user buffer */
bool set; /* get or set request (optional) */
uint used; /* bytes read or written (optional) */
uint needed; /* bytes needed (optional) */
uint driver; /* to identify target driver */
} dhd_ioctl_t;
/* per-driver magic numbers */
#define DHD_IOCTL_MAGIC 0x00444944
/* bump this number if you change the ioctl interface */
#define DHD_IOCTL_VERSION 1
#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */
#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */
/* common ioctl definitions */
#define DHD_GET_MAGIC 0
#define DHD_GET_VERSION 1
#define DHD_GET_VAR 2
#define DHD_SET_VAR 3
/* message levels */
#define DHD_ERROR_VAL 0x0001
#define DHD_TRACE_VAL 0x0002
#define DHD_INFO_VAL 0x0004
#define DHD_DATA_VAL 0x0008
#define DHD_CTL_VAL 0x0010
#define DHD_TIMER_VAL 0x0020
#define DHD_HDRS_VAL 0x0040
#define DHD_BYTES_VAL 0x0080
#define DHD_INTR_VAL 0x0100
#define DHD_LOG_VAL 0x0200
#define DHD_GLOM_VAL 0x0400
#define DHD_EVENT_VAL 0x0800
#define DHD_BTA_VAL 0x1000
#define DHD_ISCAN_VAL 0x2000
#ifdef SDTEST
/* For pktgen iovar */
typedef struct dhd_pktgen {
uint version; /* To allow structure change tracking */
uint freq; /* Max ticks between tx/rx attempts */
uint count; /* Test packets to send/rcv each attempt */
uint print; /* Print counts every <print> attempts */
uint total; /* Total packets (or bursts) */
uint minlen; /* Minimum length of packets to send */
uint maxlen; /* Maximum length of packets to send */
uint numsent; /* Count of test packets sent */
uint numrcvd; /* Count of test packets received */
uint numfail; /* Count of test send failures */
uint mode; /* Test mode (type of test packets) */
uint stop; /* Stop after this many tx failures */
} dhd_pktgen_t;
/* Version in case structure changes */
#define DHD_PKTGEN_VERSION 2
/* Type of test packets to use */
#define DHD_PKTGEN_ECHO 1 /* Send echo requests */
#define DHD_PKTGEN_SEND 2 /* Send discard packets */
#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */
#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous
tx dongle */
#endif /* SDTEST */
/* Enter idle immediately (no timeout) */
#define DHD_IDLE_IMMEDIATE (-1)
/* Values for idleclock iovar: other values are the sd_divisor to use
when idle */
#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change
when idle */
#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped
(and use SD1 mode) */
#endif /* _dhdioctl_h_ */

View File

@ -1,32 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _dngl_stats_h_
#define _dngl_stats_h_
typedef struct {
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 */
} dngl_stats_t;
#endif /* _dngl_stats_h_ */

View File

@ -1,75 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _hndrte_armtrap_h
#define _hndrte_armtrap_h
/* ARM trap handling */
/* Trap types defined by ARM (see arminc.h) */
/* Trap locations in lo memory */
#define TRAP_STRIDE 4
#define FIRST_TRAP TR_RST
#define LAST_TRAP (TR_FIQ * TRAP_STRIDE)
#if defined(__ARM_ARCH_4T__)
#define MAX_TRAP_TYPE (TR_FIQ + 1)
#elif defined(__ARM_ARCH_7M__)
#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS)
#endif /* __ARM_ARCH_7M__ */
/* The trap structure is defined here as offsets for assembly */
#define TR_TYPE 0x00
#define TR_EPC 0x04
#define TR_CPSR 0x08
#define TR_SPSR 0x0c
#define TR_REGS 0x10
#define TR_REG(n) (TR_REGS + (n) * 4)
#define TR_SP TR_REG(13)
#define TR_LR TR_REG(14)
#define TR_PC TR_REG(15)
#define TRAP_T_SIZE 80
#ifndef _LANGUAGE_ASSEMBLY
typedef struct _trap_struct {
u32 type;
u32 epc;
u32 cpsr;
u32 spsr;
u32 r0;
u32 r1;
u32 r2;
u32 r3;
u32 r4;
u32 r5;
u32 r6;
u32 r7;
u32 r8;
u32 r9;
u32 r10;
u32 r11;
u32 r12;
u32 r13;
u32 r14;
u32 pc;
} trap_t;
#endif /* !_LANGUAGE_ASSEMBLY */
#endif /* _hndrte_armtrap_h */

View File

@ -1,62 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _hndrte_cons_h
#define _hndrte_cons_h
#define CBUF_LEN (128)
#define LOG_BUF_LEN 1024
typedef struct {
u32 buf; /* Can't be pointer on (64-bit) hosts */
uint buf_size;
uint idx;
char *_buf_compat; /* Redundant pointer for backward compat. */
} hndrte_log_t;
typedef struct {
/* Virtual UART
* When there is no UART (e.g. Quickturn),
* the host should write a complete
* input line directly into cbuf and then write
* the length into vcons_in.
* This may also be used when there is a real UART
* (at risk of conflicting with
* the real UART). vcons_out is currently unused.
*/
volatile uint vcons_in;
volatile uint vcons_out;
/* Output (logging) buffer
* Console output is written to a ring buffer log_buf at index log_idx.
* The host may read the output when it sees log_idx advance.
* Output will be lost if the output wraps around faster than the host
* polls.
*/
hndrte_log_t log;
/* Console input line buffer
* Characters are read one at a time into cbuf
* until <CR> is received, then
* the buffer is processed as a command line.
* Also used for virtual UART.
*/
uint cbuf_idx;
char cbuf[CBUF_LEN];
} hndrte_cons_t;
#endif /* _hndrte_cons_h */

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _MSGTRACE_H
#define _MSGTRACE_H
#define MSGTRACE_VERSION 1
/* Message trace header */
typedef struct msgtrace_hdr {
u8 version;
u8 spare;
u16 len; /* Len of the trace */
u32 seqnum; /* Sequence number of message. Useful
* if the messsage has been lost
* because of DMA error or a bus reset
* (ex: SDIO Func2)
*/
u32 discarded_bytes; /* Number of discarded bytes because of
trace overflow */
u32 discarded_printf; /* Number of discarded printf
because of trace overflow */
} __attribute__((packed)) msgtrace_hdr_t;
#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t)
/* The hbus driver generates traces when sending a trace message.
* This causes endless traces.
* This flag must be set to true in any hbus traces.
* The flag is reset in the function msgtrace_put.
* This prevents endless traces but generates hasardous
* lost of traces only in bus device code.
* It is recommendat to set this flag in macro SD_TRACE
* but not in SD_ERROR for avoiding missing
* hbus error traces. hbus error trace should not generates endless traces.
*/
extern bool msgtrace_hbus_trace;
typedef void (*msgtrace_func_send_t) (void *hdl1, void *hdl2, u8 *hdr,
u16 hdrlen, u8 *buf,
u16 buflen);
extern void msgtrace_sent(void);
extern void msgtrace_put(char *buf, int count);
extern void msgtrace_init(void *hdl1, void *hdl2,
msgtrace_func_send_t func_send);
#endif /* _MSGTRACE_H */

View File

@ -0,0 +1,347 @@
/*
* 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>
extern const uint brcmf_sdio_msglevel;
#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
#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */
/* function 1 miscellaneous registers */
#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */
#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */
#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */
#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */
#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */
#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */
#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */
#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */
#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */
#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */
/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */
#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */
#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */
#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */
#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */
#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */
#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */
#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */
#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */
#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */
#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */
#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 */
#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */
#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */
/* some duplication with sbsdpcmdev.h here */
/* 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 */
#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */
#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
/* forward declarations */
struct brcmf_sdio_card;
struct brcmf_sdreg {
int func;
int offset;
int value;
};
struct sdioh_info {
struct osl_info *osh; /* osh handler */
bool client_intr_enabled; /* interrupt connnected flag */
bool intr_handler_valid; /* client driver interrupt handler valid */
void (*intr_handler)(void *); /* registered interrupt handler */
void *intr_handler_arg; /* argument to call interrupt handler */
u16 intmask; /* Current active interrupts */
void *sdos_info; /* Pointer to per-OS private data */
uint irq; /* Client irq */
int intrcount; /* Client interrupts */
bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */
/* Must be on for sd_multiblock to be effective */
bool use_client_ints; /* If this is false, make sure to restore */
int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
u8 num_funcs; /* Supported funcs on client */
u32 com_cis_ptr;
u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
uint max_dma_len;
uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */
/* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */
};
struct brcmf_sdmmc_instance {
struct sdioh_info *sd;
struct sdio_func *func[SDIOD_MAX_IOFUNCS];
u32 host_claimed;
};
/* Attach and build an interface to the underlying SD host driver.
* - Allocates resources (structs, arrays, mem, OS handles, etc) needed by
* brcmf_sdcard.
* - Returns the sdio card handle and virtual address base for register access.
* The returned handle should be used in all subsequent calls, but the bcmsh
* implementation may maintain a single "default" handle (e.g. the first or
* most recent one) to enable single-instance implementations to pass NULL.
*/
extern struct brcmf_sdio_card*
brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq);
/* Detach - freeup resources allocated in attach */
extern int brcmf_sdcard_detach(struct brcmf_sdio_card *card);
/* Enable/disable SD interrupt */
extern int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card);
extern int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card);
/* Register/deregister device interrupt handler. */
extern int
brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
void (*fn)(void *), void *argh);
extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card);
/* 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_card *card, uint func,
u32 addr, int *err);
extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint func,
u32 addr, u8 data, int *err);
/* Read/Write 4bytes from/to cfg space */
extern u32
brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
u32 addr, int *err);
extern void brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card,
uint fnc_num, u32 addr,
u32 data, int *err);
/* Read CIS content for specified function.
* fn: function whose CIS is being requested (0 is common CIS)
* cis: pointer to memory location to place results
* length: number of bytes to read
* Internally, this routine uses the values from the cis base regs (0x9-0xB)
* to form an SDIO-space address to read the data from.
*/
extern int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func,
u8 *cis, uint length);
/* 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_card *card, u32 addr, uint size);
extern u32
brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
u32 data);
/* Indicate if last reg read/write failed */
extern bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card);
/* 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_card *card, u32 addr, uint fn,
uint flags, u8 *buf, uint nbytes, void *pkt,
void (*complete)(void *handle, int status,
bool sync_waiting),
void *handle);
extern int
brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt,
void (*complete)(void *handle, int status,
bool sync_waiting),
void *handle);
/* Flags bits */
#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */
#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */
#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */
/* Pending (non-error) return code */
#define BCME_PENDING 1
/* 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_card *card, uint rw, u32 addr,
u8 *buf, uint nbytes);
/* Issue an abort to the specified function */
extern int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn);
/* Returns the "Device ID" of target device on the SDIO bus. */
extern int brcmf_sdcard_query_device(struct brcmf_sdio_card *card);
/* Miscellaneous knob tweaker. */
extern int brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
void *params, int plen, void *arg, int len,
bool set);
/* helper functions */
/* callback functions */
struct brcmf_sdioh_driver {
/* attach to device */
void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot,
u16 func, uint bustype, u32 regsva, void *param);
/* detach from device */
void (*detach) (void *ch);
};
struct sdioh_info;
/* platform specific/high level functions */
extern int brcmf_sdio_function_init(void);
extern int brcmf_sdio_register(struct brcmf_sdioh_driver *driver);
extern void brcmf_sdio_unregister(void);
extern void brcmf_sdio_function_cleanup(void);
extern int brcmf_sdio_probe(struct device *dev);
extern int brcmf_sdio_remove(struct device *dev);
/* Function to return current window addr */
extern u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card);
/* Allocate/init/free per-OS private data */
extern int brcmf_sdioh_osinit(struct sdioh_info *sd);
extern void brcmf_sdioh_osfree(struct sdioh_info *sd);
/* Core interrupt enable/disable of device interrupts */
extern void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd);
extern void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd);
/* 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 struct sdioh_info *brcmf_sdioh_attach(void *cfghdl, uint irq);
extern int brcmf_sdioh_detach(struct sdioh_info *si);
extern int
brcmf_sdioh_interrupt_register(struct sdioh_info *si,
void (*sdioh_cb_fn)(void *), void *argh);
extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *si);
/* enable or disable SD interrupt */
extern int
brcmf_sdioh_interrupt_set(struct sdioh_info *si, bool enable_disable);
/* read or write one byte using cmd52 */
extern int
brcmf_sdioh_request_byte(struct sdioh_info *si, uint rw, uint fnc, uint addr,
u8 *byte);
/* read or write 2/4 bytes using cmd53 */
extern int
brcmf_sdioh_request_word(struct sdioh_info *si, uint cmd_type,
uint rw, uint fnc, uint addr,
u32 *word, uint nbyte);
/* read or write any buffer using cmd53 */
extern int
brcmf_sdioh_request_buffer(struct sdioh_info *si, uint pio_dma,
uint fix_inc, uint rw, uint fnc_num,
u32 addr, uint regwidth,
u32 buflen, u8 *buffer, struct sk_buff *pkt);
/* get cis data */
extern int
brcmf_sdioh_cis_read(struct sdioh_info *si, uint fuc, u8 *cis, u32 length);
extern int
brcmf_sdioh_cfg_read(struct sdioh_info *si, uint fuc, u32 addr, u8 *data);
extern int
brcmf_sdioh_cfg_write(struct sdioh_info *si, uint fuc, u32 addr, u8 *data);
/* handle iovars */
extern int brcmf_sdioh_iovar_op(struct sdioh_info *si, const char *name,
void *params, int plen, void *arg, int len, bool set);
/* Issue abort to the specified function and clear controller as needed */
extern int brcmf_sdioh_abort(struct sdioh_info *si, uint fnc);
/* Watchdog timer interface for pm ops */
extern void brcmf_sdio_wdtmr_enable(bool enable);
extern uint sd_msglevel; /* Debug message level */
extern struct brcmf_sdmmc_instance *gInstance;
#endif /* _BRCM_SDH_H_ */

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SDIOH_H
#define _SDIOH_H
#define SD_SysAddr 0x000
#define SD_BlockSize 0x004
#define SD_BlockCount 0x006
#define SD_Arg0 0x008
#define SD_Arg1 0x00A
#define SD_TransferMode 0x00C
#define SD_Command 0x00E
#define SD_Response0 0x010
#define SD_Response1 0x012
#define SD_Response2 0x014
#define SD_Response3 0x016
#define SD_Response4 0x018
#define SD_Response5 0x01A
#define SD_Response6 0x01C
#define SD_Response7 0x01E
#define SD_BufferDataPort0 0x020
#define SD_BufferDataPort1 0x022
#define SD_PresentState 0x024
#define SD_HostCntrl 0x028
#define SD_PwrCntrl 0x029
#define SD_BlockGapCntrl 0x02A
#define SD_WakeupCntrl 0x02B
#define SD_ClockCntrl 0x02C
#define SD_TimeoutCntrl 0x02E
#define SD_SoftwareReset 0x02F
#define SD_IntrStatus 0x030
#define SD_ErrorIntrStatus 0x032
#define SD_IntrStatusEnable 0x034
#define SD_ErrorIntrStatusEnable 0x036
#define SD_IntrSignalEnable 0x038
#define SD_ErrorIntrSignalEnable 0x03A
#define SD_CMD12ErrorStatus 0x03C
#define SD_Capabilities 0x040
#define SD_Capabilities_Reserved 0x044
#define SD_MaxCurCap 0x048
#define SD_MaxCurCap_Reserved 0x04C
#define SD_ADMA_SysAddr 0x58
#define SD_SlotInterruptStatus 0x0FC
#define SD_HostControllerVersion 0x0FE
/* SD specific registers in PCI config space */
#define SD_SlotInfo 0x40
#endif /* _SDIOH_H */

View File

@ -1,38 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _sdiovar_h_
#define _sdiovar_h_
typedef struct sdreg {
int func;
int offset;
int value;
} sdreg_t;
/* Common msglevel constants */
#define SDH_ERROR_VAL 0x0001 /* Error */
#define SDH_TRACE_VAL 0x0002 /* Trace */
#define SDH_INFO_VAL 0x0004 /* Info */
#define SDH_DEBUG_VAL 0x0008 /* Debug */
#define SDH_DATA_VAL 0x0010 /* Data */
#define SDH_CTRL_VAL 0x0020 /* Control Regs */
#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */
#define SDH_DMA_VAL 0x0080 /* DMA */
#define NUM_PREV_TRANSACTIONS 16
#endif /* _sdiovar_h_ */

File diff suppressed because it is too large Load Diff

View File

@ -17,15 +17,11 @@
#ifndef _wl_cfg80211_h_
#define _wl_cfg80211_h_
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <wlioctl.h>
struct wl_conf;
struct wl_iface;
struct wl_priv;
struct wl_security;
struct wl_ibss;
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)
@ -38,7 +34,7 @@ struct wl_ibss;
#define WL_ERR(fmt, args...) \
do { \
if (wl_dbg_level & WL_DBG_ERR) { \
if (brcmf_dbg_level & WL_DBG_ERR) { \
if (net_ratelimit()) { \
printk(KERN_ERR "ERROR @%s : " fmt, \
__func__, ##args); \
@ -49,7 +45,7 @@ do { \
#if (defined BCMDBG)
#define WL_INFO(fmt, args...) \
do { \
if (wl_dbg_level & WL_DBG_INFO) { \
if (brcmf_dbg_level & WL_DBG_INFO) { \
if (net_ratelimit()) { \
printk(KERN_ERR "INFO @%s : " fmt, \
__func__, ##args); \
@ -59,7 +55,7 @@ do { \
#define WL_TRACE(fmt, args...) \
do { \
if (wl_dbg_level & WL_DBG_TRACE) { \
if (brcmf_dbg_level & WL_DBG_TRACE) { \
if (net_ratelimit()) { \
printk(KERN_ERR "TRACE @%s : " fmt, \
__func__, ##args); \
@ -69,7 +65,7 @@ do { \
#define WL_SCAN(fmt, args...) \
do { \
if (wl_dbg_level & WL_DBG_SCAN) { \
if (brcmf_dbg_level & WL_DBG_SCAN) { \
if (net_ratelimit()) { \
printk(KERN_ERR "SCAN @%s : " fmt, \
__func__, ##args); \
@ -79,7 +75,7 @@ do { \
#define WL_CONN(fmt, args...) \
do { \
if (wl_dbg_level & WL_DBG_CONN) { \
if (brcmf_dbg_level & WL_DBG_CONN) { \
if (net_ratelimit()) { \
printk(KERN_ERR "CONN @%s : " fmt, \
__func__, ##args); \
@ -94,15 +90,13 @@ do { \
#define WL_CONN(fmt, args...)
#endif /* (defined BCMDBG) */
#define WL_SCAN_RETRY_MAX 3 /* used for ibss scan */
#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_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
@ -112,15 +106,14 @@ do { \
#define WL_IOCTL_LEN_MAX 1024
#define WL_EXTRA_BUF_MAX 2048
#define WL_ISCAN_BUF_MAX 2048 /*
* the buf lengh can be WLC_IOCTL_MAXLEN (8K)
* the buf length can be BRCMF_C_IOCTL_MAXLEN
* to reduce iteration
*/
#define WL_ISCAN_TIMER_INTERVAL_MS 3000
#define WL_SCAN_ERSULTS_LAST (WL_SCAN_RESULTS_NO_MEM+1)
#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_FILE_NAME_MAX 256
#define WL_ROAM_TRIGGER_LEVEL -75
#define WL_ROAM_DELTA 20
@ -165,22 +158,8 @@ enum wl_iscan_state {
WL_ISCAN_STATE_SCANING
};
/* fw downloading status */
enum wl_fw_status {
WL_FW_LOADING_DONE,
WL_NVRAM_LOADING_DONE
};
/* beacon / probe_response */
struct beacon_proberesp {
__le64 timestamp;
__le16 beacon_int;
__le16 capab_info;
u8 variable[0];
} __attribute__ ((packed));
/* dongle configuration */
struct wl_conf {
struct brcmf_cfg80211_conf {
u32 mode; /* adhoc , infrastructure or ap */
u32 frag_threshold;
u32 rts_threshold;
@ -191,51 +170,43 @@ struct wl_conf {
};
/* cfg80211 main event loop */
struct wl_event_loop {
s32(*handler[WLC_E_LAST]) (struct wl_priv *wl,
struct brcmf_cfg80211_event_loop {
s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
struct net_device *ndev,
const wl_event_msg_t *e, void *data);
const struct brcmf_event_msg *e,
void *data);
};
/* representing interface of cfg80211 plane */
struct wl_iface {
struct wl_priv *wl;
struct brcmf_cfg80211_iface {
struct brcmf_cfg80211_priv *cfg_priv;
};
struct wl_dev {
struct brcmf_cfg80211_dev {
void *driver_data; /* to store cfg80211 object information */
};
/* bss inform structure for cfg80211 interface */
struct wl_cfg80211_bss_info {
u16 band;
u16 channel;
s16 rssi;
u16 frame_len;
u8 frame_buf[1];
};
/* basic structure of scan request */
struct wl_scan_req {
struct wlc_ssid ssid;
struct brcmf_cfg80211_scan_req {
struct brcmf_ssid ssid;
};
/* basic structure of information element */
struct wl_ie {
struct brcmf_cfg80211_ie {
u16 offset;
u8 buf[WL_TLV_INFO_MAX];
};
/* event queue for cfg80211 main event */
struct wl_event_q {
struct brcmf_cfg80211_event_q {
struct list_head eq_list;
u32 etype;
wl_event_msg_t emsg;
struct brcmf_event_msg emsg;
s8 edata[1];
};
/* security information with currently associated ap */
struct wl_security {
struct brcmf_cfg80211_security {
u32 wpa_versions;
u32 auth_type;
u32 cipher_pairwise;
@ -244,7 +215,7 @@ struct wl_security {
};
/* ibss information for currently joined ibss network */
struct wl_ibss {
struct brcmf_cfg80211_ibss {
u8 beacon_interval; /* in millisecond */
u8 atim; /* in millisecond */
s8 join_only;
@ -253,24 +224,25 @@ struct wl_ibss {
};
/* dongle profile */
struct wl_profile {
struct brcmf_cfg80211_profile {
u32 mode;
struct wlc_ssid ssid;
struct brcmf_ssid ssid;
u8 bssid[ETH_ALEN];
u16 beacon_interval;
u8 dtim_period;
struct wl_security sec;
struct wl_ibss ibss;
struct brcmf_cfg80211_security sec;
struct brcmf_cfg80211_ibss ibss;
s32 band;
};
/* dongle iscan event loop */
struct wl_iscan_eloop {
s32(*handler[WL_SCAN_ERSULTS_LAST]) (struct wl_priv *wl);
struct brcmf_cfg80211_iscan_eloop {
s32 (*handler[WL_SCAN_ERSULTS_LAST])
(struct brcmf_cfg80211_priv *cfg_priv);
};
/* dongle iscan controller */
struct wl_iscan_ctrl {
struct brcmf_cfg80211_iscan_ctrl {
struct net_device *dev;
struct timer_list timer;
u32 timer_ms;
@ -278,69 +250,57 @@ struct wl_iscan_ctrl {
s32 state;
struct task_struct *tsk;
struct semaphore sync;
struct wl_iscan_eloop el;
struct brcmf_cfg80211_iscan_eloop el;
void *data;
s8 ioctl_buf[WLC_IOCTL_SMLEN];
s8 ioctl_buf[BRCMF_C_IOCTL_SMLEN];
s8 scan_buf[WL_ISCAN_BUF_MAX];
};
/* association inform */
struct wl_connect_info {
struct brcmf_cfg80211_connect_info {
u8 *req_ie;
s32 req_ie_len;
u8 *resp_ie;
s32 resp_ie_len;
};
/* firmware /nvram downloading controller */
struct wl_fw_ctrl {
const struct firmware *fw_entry;
unsigned long status;
u32 ptr;
s8 fw_name[WL_FILE_NAME_MAX];
s8 nvram_name[WL_FILE_NAME_MAX];
};
/* assoc ie length */
struct wl_assoc_ielen {
struct brcmf_cfg80211_assoc_ielen {
u32 req_len;
u32 resp_len;
};
/* wpa2 pmk list */
struct wl_pmk_list {
struct brcmf_cfg80211_pmk_list {
pmkid_list_t pmkids;
pmkid_t foo[MAXPMKID - 1];
};
/* dongle private data of cfg80211 interface */
struct wl_priv {
struct brcmf_cfg80211_priv {
struct wireless_dev *wdev; /* representing wl cfg80211 device */
struct wl_conf *conf; /* dongle configuration */
struct brcmf_cfg80211_conf *conf; /* dongle configuration */
struct cfg80211_scan_request *scan_request; /* scan request
object */
struct wl_event_loop el; /* main event loop */
struct brcmf_cfg80211_event_loop el; /* main event loop */
struct list_head eq_list; /* used for event queue */
spinlock_t eq_lock; /* for event queue synchronization */
struct mutex usr_sync; /* maily for dongle up/down synchronization */
struct wl_scan_results *bss_list; /* bss_list holding scanned
struct brcmf_scan_results *bss_list; /* bss_list holding scanned
ap information */
struct wl_scan_results *scan_results;
struct wl_scan_req *scan_req_int; /* scan request object for
internal purpose */
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 wl_ie ie; /* information element object for
struct brcmf_cfg80211_ie ie; /* information element object for
internal purpose */
struct semaphore event_sync; /* for synchronization of main event
thread */
struct wl_profile *profile; /* holding dongle profile */
struct wl_iscan_ctrl *iscan; /* iscan controller */
struct wl_connect_info conn_info; /* association information
container */
struct wl_fw_ctrl *fw; /* control firwmare / nvram paramter
downloading */
struct wl_pmk_list *pmk_list; /* wpa2 pmk list */
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 task_struct *event_tsk; /* task of main event handler thread */
unsigned long status; /* current dongle status */
void *pub;
@ -361,26 +321,21 @@ struct wl_priv {
u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
};
#define wl_to_dev(w) (wiphy_dev(wl->wdev->wiphy))
#define wl_to_wiphy(w) (w->wdev->wiphy)
#define wiphy_to_wl(w) ((struct wl_priv *)(wiphy_priv(w)))
#define wl_to_wdev(w) (w->wdev)
#define wdev_to_wl(w) ((struct wl_priv *)(wdev_priv(w)))
#define wl_to_ndev(w) (w->wdev->netdev)
#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
#define ci_to_wl(c) (ci->wl)
#define wl_to_ci(w) (&w->ci)
#define wl_to_sr(w) (w->scan_req_int)
#define wl_to_ie(w) (&w->ie)
#define iscan_to_wl(i) ((struct wl_priv *)(i->data))
#define wl_to_iscan(w) (w->iscan)
#define wl_to_conn(w) (&w->conn_info)
#define cfg_to_wiphy(w) (w->wdev->wiphy)
#define wiphy_to_cfg(w) ((struct brcmf_cfg80211_priv *)(wiphy_priv(w)))
#define cfg_to_wdev(w) (w->wdev)
#define wdev_to_cfg(w) ((struct brcmf_cfg80211_priv *)(wdev_priv(w)))
#define cfg_to_ndev(w) (w->wdev->netdev)
#define ndev_to_cfg(n) (wdev_to_cfg(n->ieee80211_ptr))
#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
#define cfg_to_iscan(w) (w->iscan)
#define cfg_to_conn(w) (&w->conn_info)
static inline struct wl_bss_info *next_bss(struct wl_scan_results *list,
struct wl_bss_info *bss)
static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list,
struct brcmf_bss_info *bss)
{
return bss = bss ?
(struct wl_bss_info *)((unsigned long)bss +
(struct brcmf_bss_info *)((unsigned long)bss +
le32_to_cpu(bss->length)) :
list->bss_info;
}
@ -388,26 +343,14 @@ static inline struct wl_bss_info *next_bss(struct wl_scan_results *list,
#define for_each_bss(list, bss, __i) \
for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
extern s32 wl_cfg80211_attach(struct net_device *ndev, void *data);
extern void wl_cfg80211_detach(void);
extern s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data);
extern void brcmf_cfg80211_detach(void);
/* event handler from dongle */
extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e,
void *data);
extern void wl_cfg80211_sdio_func(void *func); /* set sdio function info */
extern struct sdio_func *wl_cfg80211_get_sdio_func(void); /* set sdio function info */
extern s32 wl_cfg80211_up(void); /* dongle up */
extern s32 wl_cfg80211_down(void); /* dongle down */
extern void wl_cfg80211_dbg_level(u32 level); /* set dongle
debugging level */
extern void *wl_cfg80211_request_fw(s8 *file_name); /* request fw /nvram
downloading */
extern s32 wl_cfg80211_read_fw(s8 *buf, u32 size); /* read fw
image */
extern void wl_cfg80211_release_fw(void); /* release fw */
extern s8 *wl_cfg80211_get_fwname(void); /* get firmware name for
the dongle */
extern s8 *wl_cfg80211_get_nvramname(void); /* get nvram name for
the dongle */
extern void wl_os_wd_timer(struct net_device *ndev, uint wdtick);
extern void brcmf_cfg80211_event(struct net_device *ndev,
const struct brcmf_event_msg *e, void *data);
extern void brcmf_cfg80211_sdio_func(void *func); /* set sdio function info */
extern struct sdio_func *brcmf_cfg80211_get_sdio_func(void);
extern s32 brcmf_cfg80211_up(void); /* dongle up */
extern s32 brcmf_cfg80211_down(void); /* dongle down */
#endif /* _wl_cfg80211_h_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,142 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _wl_iw_h_
#define _wl_iw_h_
#include <linux/wireless.h>
#include <wlioctl.h>
#define WL_SCAN_PARAMS_SSID_MAX 10
#define GET_SSID "SSID="
#define GET_CHANNEL "CH="
#define GET_NPROBE "NPROBE="
#define GET_ACTIVE_ASSOC_DWELL "ACTIVE="
#define GET_PASSIVE_ASSOC_DWELL "PASSIVE="
#define GET_HOME_DWELL "HOME="
#define GET_SCAN_TYPE "TYPE="
#define BAND_GET_CMD "BANDGET"
#define BAND_SET_CMD "BANDSET"
#define DTIM_SKIP_GET_CMD "DTIMSKIPGET"
#define DTIM_SKIP_SET_CMD "DTIMSKIPSET"
#define SETSUSPEND_CMD "SETSUSPENDOPT"
#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR"
#define PNOSETUP_SET_CMD "PNOSETUP"
#define PNOENABLE_SET_CMD "PNOFORCE"
#define PNODEBUG_SET_CMD "PNODEBUG"
typedef struct wl_iw_extra_params {
int target_channel;
} wl_iw_extra_params_t;
#define WL_IW_RSSI_MINVAL -200
#define WL_IW_RSSI_NO_SIGNAL -91
#define WL_IW_RSSI_VERY_LOW -80
#define WL_IW_RSSI_LOW -70
#define WL_IW_RSSI_GOOD -68
#define WL_IW_RSSI_VERY_GOOD -58
#define WL_IW_RSSI_EXCELLENT -57
#define WL_IW_RSSI_INVALID 0
#define MAX_WX_STRING 80
#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1)
#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3)
#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5)
#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7)
#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9)
#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11)
#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13)
#define WL_SET_AP_CFG (SIOCIWFIRSTPRIV+15)
#define WL_AP_STA_LIST (SIOCIWFIRSTPRIV+17)
#define WL_AP_MAC_FLTR (SIOCIWFIRSTPRIV+19)
#define WL_AP_BSS_START (SIOCIWFIRSTPRIV+21)
#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23)
#define WL_AP_STOP (SIOCIWFIRSTPRIV+25)
#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27)
#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+29)
#define WL_AP_SPARE3 (SIOCIWFIRSTPRIV+31)
#define G_SCAN_RESULTS (8*1024)
#define WE_ADD_EVENT_FIX 0x80
#define G_WLAN_SET_ON 0
#define G_WLAN_SET_OFF 1
#define CHECK_EXTRA_FOR_NULL(extra) \
if (!extra) { \
WL_ERROR("%s: error : extra is null pointer\n", __func__); \
return -EINVAL; \
}
typedef struct wl_iw {
char nickname[IW_ESSID_MAX_SIZE];
struct iw_statistics wstats;
int spy_num;
u32 pwsec;
u32 gwsec;
bool privacy_invoked;
u8 spy_addr[IW_MAX_SPY][ETH_ALEN];
struct iw_quality spy_qual[IW_MAX_SPY];
void *wlinfo;
dhd_pub_t *pub;
} wl_iw_t;
#if WIRELESS_EXT > 12
#include <net/iw_handler.h>
extern const struct iw_handler_def wl_iw_handler_def;
#endif
extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data);
extern int wl_iw_get_wireless_stats(struct net_device *dev,
struct iw_statistics *wstats);
int wl_iw_attach(struct net_device *dev, void *dhdp);
void wl_iw_detach(void);
extern int net_os_set_suspend_disable(struct net_device *dev, int val);
extern int net_os_set_suspend(struct net_device *dev, int val);
extern int net_os_set_dtim_skip(struct net_device *dev, int val);
extern int net_os_set_packet_filter(struct net_device *dev, int val);
#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
iwe_stream_add_event(info, stream, ends, iwe, extra)
#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \
iwe_stream_add_value(info, event, value, ends, iwe, event_len)
#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \
iwe_stream_add_point(info, stream, ends, iwe, extra)
extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
extern int dhd_pno_clean(dhd_pub_t *dhd);
extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid,
unsigned char scan_fr);
extern int dhd_pno_get_status(dhd_pub_t *dhd);
extern int dhd_dev_pno_reset(struct net_device *dev);
extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t *ssids_local,
int nssid, unsigned char scan_fr);
extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
extern int dhd_dev_get_pno_status(struct net_device *dev);
#define PNO_TLV_PREFIX 'S'
#define PNO_TLV_VERSION 1
#define PNO_TLV_SUBVERSION 0
#define PNO_TLV_RESERVED 0
#define PNO_TLV_TYPE_SSID_IE 'S'
#define PNO_TLV_TYPE_TIME 'T'
#define PNO_EVENT_UP "PNO_EVENT"
#endif /* _wl_iw_h_ */

View File

@ -28,30 +28,29 @@ ccflags-y := \
-Idrivers/staging/brcm80211/include
BRCMSMAC_OFILES := \
wl_mac80211.o \
wl_ucode_loader.o \
wlc_alloc.o \
wlc_ampdu.o \
wlc_antsel.o \
wlc_bmac.o \
wlc_channel.o \
wlc_main.o \
wlc_phy_shim.o \
wlc_pmu.o \
wlc_rate.o \
wlc_stf.o \
mac80211_if.o \
ucode_loader.o \
alloc.o \
ampdu.o \
antsel.o \
bmac.o \
channel.o \
main.o \
phy_shim.o \
pmu.o \
rate.o \
stf.o \
aiutils.o \
phy/wlc_phy_cmn.o \
phy/wlc_phy_lcn.o \
phy/wlc_phy_n.o \
phy/wlc_phytbl_lcn.o \
phy/wlc_phytbl_n.o \
phy/wlc_phy_qmath.o \
bcmotp.o \
bcmsrom.o \
hnddma.o \
nicpci.o \
nvram.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
MODULEPFX := brcmsmac

File diff suppressed because it is too large Load Diff

View File

@ -14,18 +14,10 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _aiutils_h_
#define _aiutils_h_
#ifndef _BRCM_AIUTILS_H_
#define _BRCM_AIUTILS_H_
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif
/* Include the soci specific files */
#include <aidmp.h>
#include "types.h"
/*
* SOC Interconnect Address Map.
@ -158,9 +150,7 @@
* maps all unused address ranges
*/
/* There are TWO constants on all HND chips: SI_ENUM_BASE above,
* and chipcommon being the first core:
*/
/* chipcommon being the first core: */
#define SI_CC_IDX 0
/* SOC Interconnect types (aka chip types) */
@ -225,7 +215,70 @@
#define BISZ_BSSEND_IDX 6 /* 6: bss end */
#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */
#define SI_INFO(sih) (si_info_t *)sih
#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
/* When Srom support present, fields in sromcontrol */
#define SRC_START 0x80000000
#define SRC_BUSY 0x80000000
#define SRC_OPCODE 0x60000000
#define SRC_OP_READ 0x00000000
#define SRC_OP_WRITE 0x20000000
#define SRC_OP_WRDIS 0x40000000
#define SRC_OP_WREN 0x60000000
#define SRC_OTPSEL 0x00000010
#define SRC_LOCK 0x00000008
#define SRC_SIZE_MASK 0x00000006
#define SRC_SIZE_1K 0x00000000
#define SRC_SIZE_4K 0x00000002
#define SRC_SIZE_16K 0x00000004
#define SRC_SIZE_SHIFT 1
#define SRC_PRESENT 0x00000001
/* 4330 chip-specific ChipStatus register bits */
#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */
#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */
#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */
#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */
#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */
#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */
#define CST4330_OTP_PRESENT 0x00000010
#define CST4330_LPO_AUTODET_EN 0x00000020
#define CST4330_ARMREMAP_0 0x00000040
#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */
#define CST4330_ILPDIV_EN 0x00000100
#define CST4330_LPO_SEL 0x00000200
#define CST4330_RES_INIT_MODE_SHIFT 10
#define CST4330_RES_INIT_MODE_MASK 0x00000c00
#define CST4330_CBUCK_MODE_SHIFT 12
#define CST4330_CBUCK_MODE_MASK 0x00003000
#define CST4330_CBUCK_POWER_OK 0x00004000
#define CST4330_BB_PLL_LOCKED 0x00008000
/* Package IDs */
#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */
#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */
#define BCM4717_PKG_ID 9 /* 4717 package id */
#define BCM4718_PKG_ID 10 /* 4718 package id */
#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
#define HWSIM_PKG_ID 15 /* Hardware simulator 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) */
#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */
#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */
#define SI_INFO(sih) ((struct si_info *)sih)
#define GOODCOREADDR(x, b) \
(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
@ -314,13 +367,6 @@ struct si_pub {
};
/*
* for HIGH_ONLY driver, the si_t must be writable to allow states sync from
* BMAC to HIGH driver for monolithic driver, it is readonly to prevent accident
* change
*/
typedef const struct si_pub si_t;
/*
* 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().
@ -363,8 +409,6 @@ typedef const struct si_pub si_t;
#define SI_PCIDOWN 2
#define SI_PCIUP 3
#define ISSIM_ENAB(sih) 0
/* PMU clock/power control */
#if defined(BCMPMUCTL)
#define PMUCTL_ENAB(sih) (BCMPMUCTL)
@ -404,16 +448,16 @@ typedef u32(*si_intrsoff_t) (void *intr_arg);
typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg);
typedef bool(*si_intrsenabled_t) (void *intr_arg);
typedef struct gpioh_item {
struct gpioh_item {
void *arg;
bool level;
gpio_handler_t handler;
u32 event;
struct gpioh_item *next;
} gpioh_item_t;
};
/* misc si info needed by some of the routines */
typedef struct si_info {
struct si_info {
struct si_pub pub; /* back plane public state (must be first) */
void *pbus; /* handle to bus (pci/sdio/..) */
uint dev_coreid; /* the core provides driver functions */
@ -424,10 +468,6 @@ typedef struct si_info {
void *pch; /* PCI/E core handle */
gpioh_item_t *gpioh_head; /* GPIO event handlers list */
bool memseg; /* flag to toggle MEM_SEG register */
char *vars;
uint varsz;
@ -450,97 +490,95 @@ typedef struct si_info {
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 */
} si_info_t;
};
/* AMBA Interconnect exported externs */
extern void ai_scan(si_t *sih, void *regs, uint devid);
extern void ai_scan(struct si_pub *sih, void *regs);
extern uint ai_flag(si_t *sih);
extern void ai_setint(si_t *sih, int siflag);
extern uint ai_coreidx(si_t *sih);
extern uint ai_corevendor(si_t *sih);
extern uint ai_corerev(si_t *sih);
extern bool ai_iscoreup(si_t *sih);
extern void *ai_setcoreidx(si_t *sih, uint coreidx);
extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val);
extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
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 void *ai_setcoreidx(struct si_pub *sih, uint coreidx);
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(si_t *sih, u32 bits, u32 resetbits);
extern void ai_core_disable(si_t *sih, u32 bits);
extern int ai_numaddrspaces(si_t *sih);
extern u32 ai_addrspace(si_t *sih, uint asidx);
extern u32 ai_addrspacesize(si_t *sih, uint asidx);
extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 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 si_t *ai_attach(uint pcidev, void *regs, uint bustype,
extern struct si_pub *ai_attach(void *regs, uint bustype,
void *sdh, char **vars, uint *varsz);
extern void ai_detach(si_t *sih);
extern bool ai_pci_war16165(si_t *sih);
extern void ai_detach(struct si_pub *sih);
extern bool ai_pci_war16165(struct si_pub *sih);
extern uint ai_coreid(si_t *sih);
extern uint ai_corerev(si_t *sih);
extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
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(si_t *sih, u32 offset, u32 val);
extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
extern bool ai_iscoreup(si_t *sih);
extern uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit);
extern void *ai_setcoreidx(si_t *sih, uint coreidx);
extern void *ai_setcore(si_t *sih, uint coreid, uint coreunit);
extern void *ai_switch_core(si_t *sih, uint coreid, uint *origidx,
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 *ai_setcoreidx(struct si_pub *sih, uint coreidx);
extern void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit);
extern void *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx,
uint *intr_val);
extern void ai_restore_core(si_t *sih, uint coreid, uint intr_val);
extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits);
extern void ai_core_disable(si_t *sih, u32 bits);
extern u32 ai_alp_clock(si_t *sih);
extern u32 ai_ilp_clock(si_t *sih);
extern void ai_pci_setup(si_t *sih, uint coremask);
extern void ai_setint(si_t *sih, int siflag);
extern bool ai_backplane64(si_t *sih);
extern void ai_register_intr_callback(si_t *sih, void *intrsoff_fn,
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(si_t *sih);
extern void ai_clkctl_init(si_t *sih);
extern u16 ai_clkctl_fast_pwrup_delay(si_t *sih);
extern bool ai_clkctl_cc(si_t *sih, uint mode);
extern int ai_clkctl_xtal(si_t *sih, uint what, bool on);
extern bool ai_deviceremoved(si_t *sih);
extern u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val,
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(si_t *sih);
extern bool ai_is_otp_powered(si_t *sih);
extern void ai_otp_power(si_t *sih, bool on);
extern bool ai_is_otp_disabled(struct si_pub *sih);
/* SPROM availability */
extern bool ai_is_sprom_available(si_t *sih);
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(si_t *sih, char *path, int size);
extern int ai_devpath(struct si_pub *sih, char *path, int size);
/* Read variable with prepending the devpath to the name */
extern char *ai_getdevpathvar(si_t *sih, const char *name);
extern int ai_getdevpathintvar(si_t *sih, const char *name);
extern char *ai_getdevpathvar(struct si_pub *sih, const char *name);
extern int ai_getdevpathintvar(struct si_pub *sih, const char *name);
extern void ai_pci_sleep(si_t *sih);
extern void ai_pci_down(si_t *sih);
extern void ai_pci_up(si_t *sih);
extern int ai_pci_fixcfg(si_t *sih);
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(si_t *sih, bool on);
extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
/* Enable Ex-PA for 4313 */
extern void ai_epa_4313war(si_t *sih);
extern void ai_epa_4313war(struct si_pub *sih);
char *ai_getnvramflvar(si_t *sih, const char *name);
char *ai_getnvramflvar(struct si_pub *sih, const char *name);
#endif /* _aiutils_h_ */
#endif /* _BRCM_AIUTILS_H_ */

View File

@ -13,37 +13,21 @@
* 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/types.h>
#include <bcmdefs.h>
#include <bcmutils.h>
#include <aiutils.h>
#include <wlioctl.h>
#include <sbhnddma.h>
#include <brcmu_utils.h>
#include "types.h"
#include "pub.h"
#include "main.h"
#include "alloc.h"
#include "d11.h"
#include "wlc_types.h"
#include "wlc_cfg.h"
#include "wlc_scb.h"
#include "wlc_pub.h"
#include "wlc_key.h"
#include "wlc_alloc.h"
#include "wl_dbg.h"
#include "wlc_rate.h"
#include "wlc_bsscfg.h"
#include "phy/wlc_phy_hal.h"
#include "wlc_channel.h"
#include "wlc_main.h"
static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit);
static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg);
static struct wlc_pub *wlc_pub_malloc(uint unit,
static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit);
static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg);
static struct brcms_pub *brcms_c_pub_malloc(uint unit,
uint *err, uint devid);
static void wlc_pub_mfree(struct wlc_pub *pub);
static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid);
static void brcms_c_pub_mfree(struct brcms_pub *pub);
static void brcms_c_tunables_init(struct brcms_tunables *tunables, uint devid);
static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid)
static void brcms_c_tunables_init(struct brcms_tunables *tunables, uint devid)
{
tunables->ntxd = NTXD;
tunables->nrxd = NRXD;
@ -52,33 +36,33 @@ static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid)
tunables->maxscb = MAXSCB;
tunables->ampdunummpdu = AMPDU_NUM_MPDU;
tunables->maxpktcb = MAXPKTCB;
tunables->maxucodebss = WLC_MAX_UCODE_BSS;
tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4;
tunables->maxucodebss = BRCMS_MAX_UCODE_BSS;
tunables->maxucodebss4 = BRCMS_MAX_UCODE_BSS4;
tunables->maxbss = MAXBSS;
tunables->datahiwat = WLC_DATAHIWAT;
tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT;
tunables->datahiwat = BRCMS_DATAHIWAT;
tunables->ampdudatahiwat = BRCMS_AMPDUDATAHIWAT;
tunables->rxbnd = RXBND;
tunables->txsbnd = TXSBND;
}
static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid)
static struct brcms_pub *brcms_c_pub_malloc(uint unit, uint *err, uint devid)
{
struct wlc_pub *pub;
struct brcms_pub *pub;
pub = kzalloc(sizeof(struct wlc_pub), GFP_ATOMIC);
pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
if (pub == NULL) {
*err = 1001;
goto fail;
}
pub->tunables = kzalloc(sizeof(wlc_tunables_t), GFP_ATOMIC);
pub->tunables = kzalloc(sizeof(struct brcms_tunables), GFP_ATOMIC);
if (pub->tunables == NULL) {
*err = 1028;
goto fail;
}
/* need to init the tunables now */
wlc_tunables_init(pub->tunables, devid);
brcms_c_tunables_init(pub->tunables, devid);
pub->multicast = kzalloc(ETH_ALEN * MAXMULTILIST, GFP_ATOMIC);
if (pub->multicast == NULL) {
@ -89,11 +73,11 @@ static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid)
return pub;
fail:
wlc_pub_mfree(pub);
brcms_c_pub_mfree(pub);
return NULL;
}
static void wlc_pub_mfree(struct wlc_pub *pub)
static void brcms_c_pub_mfree(struct brcms_pub *pub)
{
if (pub == NULL)
return;
@ -103,26 +87,26 @@ static void wlc_pub_mfree(struct wlc_pub *pub)
kfree(pub);
}
static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit)
static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
{
struct wlc_bsscfg *cfg;
struct brcms_bss_cfg *cfg;
cfg = kzalloc(sizeof(struct wlc_bsscfg), GFP_ATOMIC);
cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
if (cfg == NULL)
goto fail;
cfg->current_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC);
cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
if (cfg->current_bss == NULL)
goto fail;
return cfg;
fail:
wlc_bsscfg_mfree(cfg);
brcms_c_bsscfg_mfree(cfg);
return NULL;
}
static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg)
static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
{
if (cfg == NULL)
return;
@ -132,8 +116,8 @@ static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg)
kfree(cfg);
}
static void wlc_bsscfg_ID_assign(struct wlc_info *wlc,
struct wlc_bsscfg *bsscfg)
static void brcms_c_bsscfg_ID_assign(struct brcms_c_info *wlc,
struct brcms_bss_cfg *bsscfg)
{
bsscfg->ID = wlc->next_bsscfg_ID;
wlc->next_bsscfg_ID++;
@ -142,29 +126,27 @@ static void wlc_bsscfg_ID_assign(struct wlc_info *wlc,
/*
* The common driver entry routine. Error codes should be unique
*/
struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid)
struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err, uint devid)
{
struct wlc_info *wlc;
struct brcms_c_info *wlc;
wlc = kzalloc(sizeof(struct wlc_info), GFP_ATOMIC);
wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
if (wlc == NULL) {
*err = 1002;
goto fail;
}
wlc->hwrxoff = WL_HWRXOFF;
/* allocate struct wlc_pub state structure */
wlc->pub = wlc_pub_malloc(unit, err, devid);
/* allocate struct brcms_c_pub state structure */
wlc->pub = brcms_c_pub_malloc(unit, err, devid);
if (wlc->pub == NULL) {
*err = 1003;
goto fail;
}
wlc->pub->wlc = wlc;
/* allocate struct wlc_hw_info state structure */
/* allocate struct brcms_hardware state structure */
wlc->hw = kzalloc(sizeof(struct wlc_hw_info), GFP_ATOMIC);
wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
if (wlc->hw == NULL) {
*err = 1005;
goto fail;
@ -172,7 +154,7 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid)
wlc->hw->wlc = wlc;
wlc->hw->bandstate[0] =
kzalloc(sizeof(struct wlc_hwband) * MAXBANDS, GFP_ATOMIC);
kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC);
if (wlc->hw->bandstate[0] == NULL) {
*err = 1006;
goto fail;
@ -180,68 +162,62 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid)
int i;
for (i = 1; i < MAXBANDS; i++) {
wlc->hw->bandstate[i] = (struct wlc_hwband *)
wlc->hw->bandstate[i] = (struct brcms_hw_band *)
((unsigned long)wlc->hw->bandstate[0] +
(sizeof(struct wlc_hwband) * i));
(sizeof(struct brcms_hw_band) * i));
}
}
wlc->modulecb =
kzalloc(sizeof(struct modulecb) * WLC_MAXMODULES, GFP_ATOMIC);
kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC);
if (wlc->modulecb == NULL) {
*err = 1009;
goto fail;
}
wlc->default_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC);
wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
if (wlc->default_bss == NULL) {
*err = 1010;
goto fail;
}
wlc->cfg = wlc_bsscfg_malloc(unit);
wlc->cfg = brcms_c_bsscfg_malloc(unit);
if (wlc->cfg == NULL) {
*err = 1011;
goto fail;
}
wlc_bsscfg_ID_assign(wlc, wlc->cfg);
wlc->pkt_callback = kzalloc(sizeof(struct pkt_cb) *
(wlc->pub->tunables->maxpktcb + 1),
GFP_ATOMIC);
if (wlc->pkt_callback == NULL) {
*err = 1013;
goto fail;
}
brcms_c_bsscfg_ID_assign(wlc, wlc->cfg);
wlc->wsec_def_keys[0] =
kzalloc(sizeof(wsec_key_t) * WLC_DEFAULT_KEYS, GFP_ATOMIC);
kzalloc(sizeof(struct wsec_key) * BRCMS_DEFAULT_KEYS,
GFP_ATOMIC);
if (wlc->wsec_def_keys[0] == NULL) {
*err = 1015;
goto fail;
} else {
int i;
for (i = 1; i < WLC_DEFAULT_KEYS; i++) {
wlc->wsec_def_keys[i] = (wsec_key_t *)
for (i = 1; i < BRCMS_DEFAULT_KEYS; i++) {
wlc->wsec_def_keys[i] = (struct wsec_key *)
((unsigned long)wlc->wsec_def_keys[0] +
(sizeof(wsec_key_t) * i));
(sizeof(struct wsec_key) * i));
}
}
wlc->protection = kzalloc(sizeof(struct wlc_protection), GFP_ATOMIC);
wlc->protection = kzalloc(sizeof(struct brcms_protection),
GFP_ATOMIC);
if (wlc->protection == NULL) {
*err = 1016;
goto fail;
}
wlc->stf = kzalloc(sizeof(struct wlc_stf), GFP_ATOMIC);
wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
if (wlc->stf == NULL) {
*err = 1017;
goto fail;
}
wlc->bandstate[0] =
kzalloc(sizeof(struct wlcband)*MAXBANDS, GFP_ATOMIC);
kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC);
if (wlc->bandstate[0] == NULL) {
*err = 1025;
goto fail;
@ -249,20 +225,20 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid)
int i;
for (i = 1; i < MAXBANDS; i++) {
wlc->bandstate[i] =
(struct wlcband *) ((unsigned long)wlc->bandstate[0]
+ (sizeof(struct wlcband)*i));
wlc->bandstate[i] = (struct brcms_band *)
((unsigned long)wlc->bandstate[0]
+ (sizeof(struct brcms_band)*i));
}
}
wlc->corestate = kzalloc(sizeof(struct wlccore), GFP_ATOMIC);
wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
if (wlc->corestate == NULL) {
*err = 1026;
goto fail;
}
wlc->corestate->macstat_snapshot =
kzalloc(sizeof(macstat_t), GFP_ATOMIC);
kzalloc(sizeof(struct macstat), GFP_ATOMIC);
if (wlc->corestate->macstat_snapshot == NULL) {
*err = 1027;
goto fail;
@ -271,20 +247,19 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid)
return wlc;
fail:
wlc_detach_mfree(wlc);
brcms_c_detach_mfree(wlc);
return NULL;
}
void wlc_detach_mfree(struct wlc_info *wlc)
void brcms_c_detach_mfree(struct brcms_c_info *wlc)
{
if (wlc == NULL)
return;
wlc_bsscfg_mfree(wlc->cfg);
wlc_pub_mfree(wlc->pub);
brcms_c_bsscfg_mfree(wlc->cfg);
brcms_c_pub_mfree(wlc->pub);
kfree(wlc->modulecb);
kfree(wlc->default_bss);
kfree(wlc->pkt_callback);
kfree(wlc->wsec_def_keys[0]);
kfree(wlc->protection);
kfree(wlc->stf);

View File

@ -14,5 +14,6 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
extern struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid);
extern void wlc_detach_mfree(struct wlc_info *wlc);
extern struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err,
uint devid);
extern void brcms_c_detach_mfree(struct brcms_c_info *wlc);

View File

@ -13,30 +13,14 @@
* 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 <net/mac80211.h>
#include <bcmdefs.h>
#include <bcmutils.h>
#include <aiutils.h>
#include <wlioctl.h>
#include <sbhnddma.h>
#include <hnddma.h>
#include <d11.h>
#include "wlc_types.h"
#include "wlc_cfg.h"
#include "wlc_rate.h"
#include "wlc_scb.h"
#include "wlc_pub.h"
#include "wlc_key.h"
#include "phy/wlc_phy_hal.h"
#include "wlc_antsel.h"
#include "wl_export.h"
#include "wl_dbg.h"
#include "wlc_channel.h"
#include "wlc_main.h"
#include "wlc_ampdu.h"
#include "rate.h"
#include "scb.h"
#include "phy/phy_hal.h"
#include "antsel.h"
#include "main.h"
#include "ampdu.h"
#define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */
#define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */
@ -76,7 +60,7 @@
* This allows to maintain a specific state independently of
* how often and/or when the wlc counters are updated.
*/
typedef struct wlc_fifo_info {
struct brcms_fifo_info {
u16 ampdu_pld_size; /* number of bytes to be pre-loaded */
u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; /* per-mcs max # of mpdus in an ampdu */
u16 prev_txfunfl; /* num of underflows last read from the HW macstats counter */
@ -84,11 +68,11 @@ typedef struct wlc_fifo_info {
u32 accum_txampdu; /* num of tx ampdu since we modified pld params */
u32 prev_txampdu; /* previous reading of tx ampdu */
u32 dmaxferrate; /* estimated dma avg xfer rate in kbits/sec */
} wlc_fifo_info_t;
};
/* AMPDU module specific state */
struct ampdu_info {
struct wlc_info *wlc; /* pointer to main wlc structure */
struct brcms_c_info *wlc; /* pointer to main wlc structure */
int scb_handle; /* scb cubby handle to retrieve data from scb */
u8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */
u8 ba_tx_wsize; /* Tx ba window size (in pdu) */
@ -110,7 +94,8 @@ struct ampdu_info {
u32 tx_max_funl; /* underflows should be kept such that
* (tx_max_funfl*underflows) < tx frames
*/
wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO]; /* table of fifo infos */
/* table of fifo infos */
struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
};
@ -126,35 +111,36 @@ struct cb_del_ampdu_pars {
#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu))
#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid]))
static void wlc_ffpld_init(struct ampdu_info *ampdu);
static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f);
static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f);
static void brcms_c_ffpld_init(struct ampdu_info *ampdu);
static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int f);
static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f);
static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu,
scb_ampdu_t *scb_ampdu,
u8 tid, bool override);
static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur);
static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb);
static void scb_ampdu_update_config_all(struct ampdu_info *ampdu);
static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu,
u8 dur);
static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
struct scb *scb);
static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu);
#define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0)
#define brcms_c_ampdu_txflowcontrol(a, b, c) do {} while (0)
static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu,
struct scb *scb,
struct sk_buff *p, tx_status_t *txs,
u32 frmtxstatus, u32 frmtxstatus2);
static bool wlc_ampdu_cap(struct ampdu_info *ampdu);
static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on);
static void
brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu,
struct scb *scb,
struct sk_buff *p, struct tx_status *txs,
u32 frmtxstatus, u32 frmtxstatus2);
struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc)
static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu);
static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on);
struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
{
struct ampdu_info *ampdu;
int i;
ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
if (!ampdu) {
wiphy_err(wlc->wiphy, "wl%d: wlc_ampdu_attach: out of mem\n",
wlc->pub->unit);
wiphy_err(wlc->wiphy, "wl%d: brcms_c_ampdu_attach: out of mem"
"\n", wlc->pub->unit);
return NULL;
}
ampdu->wlc = wlc;
@ -178,7 +164,7 @@ struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc)
ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
/* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */
if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
else
ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
@ -190,18 +176,18 @@ struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc)
ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
}
ampdu_update_max_txlen(ampdu, ampdu->dur);
brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
ampdu->mfbr = false;
/* try to set ampdu to the default value */
wlc_ampdu_set(ampdu, wlc->pub->_ampdu);
brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
wlc_ffpld_init(ampdu);
brcms_c_ffpld_init(ampdu);
return ampdu;
}
void wlc_ampdu_detach(struct ampdu_info *ampdu)
void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
{
int i;
@ -213,13 +199,14 @@ void wlc_ampdu_detach(struct ampdu_info *ampdu)
kfree(ampdu->ini_free[i]);
}
wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu);
brcms_c_module_unregister(ampdu->wlc->pub, "ampdu", ampdu);
kfree(ampdu);
}
static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb)
static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
struct scb *scb)
{
scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
struct scb_ampdu *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
int i;
scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu;
@ -236,24 +223,24 @@ static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb)
scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE);
if (scb_ampdu->max_rxlen)
scb_ampdu->release =
min_t(u8, scb_ampdu->release, scb_ampdu->max_rxlen / 1600);
if (scb_ampdu->max_rx_ampdu_bytes)
scb_ampdu->release = min_t(u8, scb_ampdu->release,
scb_ampdu->max_rx_ampdu_bytes / 1600);
scb_ampdu->release = min(scb_ampdu->release,
ampdu->fifo_tb[TX_AC_BE_FIFO].
mcs2ampdu_table[FFPLD_MAX_MCS]);
}
static void scb_ampdu_update_config_all(struct ampdu_info *ampdu)
static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
{
scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb);
brcms_c_scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb);
}
static void wlc_ffpld_init(struct ampdu_info *ampdu)
static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
{
int i, j;
wlc_fifo_info_t *fifo;
struct brcms_fifo_info *fifo;
for (j = 0; j < NUM_FFPLD_FIFO; j++) {
fifo = (ampdu->fifo_tb + j);
@ -274,7 +261,7 @@ static void wlc_ffpld_init(struct ampdu_info *ampdu)
* Return 1 if pre-loading not active, -1 if not an underflow event,
* 0 if pre-loading module took care of the event.
*/
static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid)
static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
{
struct ampdu_info *ampdu = wlc->ampdu;
u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false);
@ -283,14 +270,14 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid)
u32 current_ampdu_cnt = 0;
u16 max_pld_size;
u32 new_txunfl;
wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid);
struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
uint xmtfifo_sz;
u16 cur_txunfl;
/* return if we got here for a different reason than underflows */
cur_txunfl =
wlc_read_shm(wlc,
M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid]));
cur_txunfl = brcms_c_read_shm(wlc,
M_UCODE_MACSTAT +
offsetof(struct macstat, txfunfl[fid]));
new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
if (new_txunfl == 0) {
BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
@ -302,9 +289,8 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid)
return 1;
/* check if fifo is big enough */
if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) {
if (brcms_c_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz))
return -1;
}
if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
return 1;
@ -356,7 +342,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid)
fifo->ampdu_pld_size = max_pld_size;
/* update scb release size */
scb_ampdu_update_config_all(ampdu);
brcms_c_scb_ampdu_update_config_all(ampdu);
/*
compute a new dma xfer rate for max_mpdu @ max mcs.
@ -383,22 +369,22 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid)
fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
/* recompute the table */
wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid);
brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
/* update scb release size */
scb_ampdu_update_config_all(ampdu);
brcms_c_scb_ampdu_update_config_all(ampdu);
}
}
fifo->accum_txfunfl = 0;
return 0;
}
static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
{
int i;
u32 phy_rate, dma_rate, tmp;
u8 max_mpdu;
wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f);
struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
/* recompute the dma rate */
/* note : we divide/multiply by 100 to avoid integer overflows */
@ -425,47 +411,53 @@ static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
}
}
static void
wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p,
uint prec)
void
brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
u8 ba_wsize, /* negotiated ba window size (in pdu) */
uint max_rx_ampdu_bytes) /* from ht_cap in beacon */
{
scb_ampdu_t *scb_ampdu;
scb_ampdu_tid_ini_t *ini;
u8 tid = (u8) (p->priority);
struct scb_ampdu *scb_ampdu;
struct scb_ampdu_tid_ini *ini;
struct ampdu_info *ampdu = wlc->ampdu;
struct scb *scb = wlc->pub->global_scb;
scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
/* initialize initiator on first packet; sends addba req */
ini = SCB_AMPDU_INI(scb_ampdu, tid);
if (ini->magic != INI_MAGIC) {
ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false);
if (!ampdu->ini_enable[tid]) {
wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
__func__, tid);
return;
}
return;
ini = SCB_AMPDU_INI(scb_ampdu, tid);
ini->tid = tid;
ini->scb = scb_ampdu->scb;
ini->ba_wsize = ba_wsize;
scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
}
int
wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
struct sk_buff **pdu, int prec)
{
struct wlc_info *wlc;
struct brcms_c_info *wlc;
struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
u8 tid, ndelim;
int err = 0;
u8 preamble_type = WLC_GF_PREAMBLE;
u8 fbr_preamble_type = WLC_GF_PREAMBLE;
u8 rts_preamble_type = WLC_LONG_PREAMBLE;
u8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE;
u8 preamble_type = BRCMS_GF_PREAMBLE;
u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
bool rr = true, fbr = false;
uint i, count = 0, fifo, seg_cnt = 0;
u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
u32 ampdu_len, maxlen = 0;
d11txh_t *txh = NULL;
u32 ampdu_len, max_ampdu_bytes = 0;
struct d11txh *txh = NULL;
u8 *plcp;
struct ieee80211_hdr *h;
struct scb *scb;
scb_ampdu_t *scb_ampdu;
scb_ampdu_tid_ini_t *ini;
struct scb_ampdu *scb_ampdu;
struct scb_ampdu_tid_ini *ini;
u8 mcs = 0;
bool use_rts = false, use_cts = false;
ratespec_t rspec = 0, rspec_fallback = 0;
@ -473,7 +465,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
struct ieee80211_rts *rts;
u8 rr_retry_limit;
wlc_fifo_info_t *f;
struct brcms_fifo_info *f;
bool fbr_iscck;
struct ieee80211_tx_info *tx_info;
u16 qlen;
@ -493,16 +485,13 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
/* Let pressure continue to build ... */
qlen = pktq_plen(&qi->q, prec);
if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) {
if (ini->tx_in_transit > 0 &&
qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) {
/* Collect multiple MPDU's to be sent in the next AMPDU */
return -EBUSY;
}
wlc_ampdu_agg(ampdu, scb, p, tid);
if (wlc->block_datafifo) {
wiphy_err(wiphy, "%s: Fifo blocked\n", __func__);
return -EBUSY;
}
/* at this point we intend to transmit an AMPDU */
rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
ampdu_len = 0;
dma_len = 0;
@ -513,7 +502,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
txrate = tx_info->status.rates;
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
err = wlc_prep_pdu(wlc, p, &fifo);
err = brcms_c_prep_pdu(wlc, p, &fifo);
} else {
wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
*pdu = NULL;
@ -523,7 +512,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
if (err) {
if (err == -EBUSY) {
wiphy_err(wiphy, "wl%d: wlc_sendampdu: "
wiphy_err(wiphy, "wl%d: sendampdu: "
"prep_xdu retry; seq 0x%x\n",
wlc->pub->unit, seq);
*pdu = p;
@ -531,14 +520,14 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
}
/* error in the packet; reject it */
wiphy_err(wiphy, "wl%d: wlc_sendampdu: prep_xdu "
wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
"rejected; seq 0x%x\n", wlc->pub->unit, seq);
*pdu = NULL;
break;
}
/* pkt is good to be aggregated */
txh = (d11txh_t *) p->data;
txh = (struct d11txh *) p->data;
plcp = (u8 *) (txh + 1);
h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
@ -562,8 +551,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
}
/* extract the length info */
len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
: WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
: BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
/* retrieve null delimiter count */
ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
@ -598,7 +587,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
len = roundup(len, 4);
ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
dma_len += (u16) bcm_pkttotlen(p);
dma_len += (u16) brcmu_pkttotlen(p);
BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
" seg_cnt %d null delim %d\n",
@ -627,19 +616,14 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
sgi = PLCP3_ISSGI(plcp3) ? 1 : 0;
mcs = plcp0 & ~MIMO_PLCP_40MHZ;
maxlen =
min(scb_ampdu->max_rxlen,
max_ampdu_bytes =
min(scb_ampdu->max_rx_ampdu_bytes,
ampdu->max_txlen[mcs][is40][sgi]);
/* XXX Fix me to honor real max_rxlen */
/* can fix this as soon as ampdu_action() in mac80211.h
* gets extra u8buf_size par */
maxlen = 64 * 1024;
if (is40)
mimo_ctlchbw =
CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC)
? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
CHSPEC_SB_UPPER(BRCMS_BAND_PI_RADIO_CHANSPEC)
? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
/* rebuild the rspec and rspec_fallback */
rspec = RSPEC_MIMORATE;
@ -663,11 +647,11 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
if (use_rts || use_cts) {
rts_rspec =
wlc_rspec_to_rts_rspec(wlc, rspec, false,
mimo_ctlchbw);
brcms_c_rspec_to_rts_rspec(wlc,
rspec, false, mimo_ctlchbw);
rts_rspec_fallback =
wlc_rspec_to_rts_rspec(wlc, rspec_fallback,
false, mimo_ctlchbw);
brcms_c_rspec_to_rts_rspec(wlc,
rspec_fallback, false, mimo_ctlchbw);
}
}
@ -693,14 +677,12 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
((u8) (p->priority) == tid)) {
plen =
bcm_pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD;
plen = brcmu_pkttotlen(p) +
AMPDU_MAX_MPDU_OVERHEAD;
plen = max(scb_ampdu->min_len, plen);
if ((plen + ampdu_len) > maxlen) {
if ((plen + ampdu_len) > max_ampdu_bytes) {
p = NULL;
wiphy_err(wiphy, "%s: Bogus plen #1\n",
__func__);
continue;
}
@ -711,7 +693,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
p = NULL;
continue;
}
p = bcm_pktq_pdeq(&qi->q, prec);
p = brcmu_pktq_pdeq(&qi->q, prec);
} else {
p = NULL;
}
@ -722,7 +704,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
if (count) {
/* patch up the last txh */
txh = (d11txh_t *) pkt[count - 1]->data;
txh = (struct d11txh *) pkt[count - 1]->data;
mcl = le16_to_cpu(txh->MacTxControlLow);
mcl &= ~TXC_AMPDU_MASK;
mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
@ -735,30 +717,31 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
/* remove the pad len from last mpdu */
fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
: WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
: BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
ampdu_len -= roundup(len, 4) - len;
/* patch up the first txh & plcp */
txh = (d11txh_t *) pkt[0]->data;
txh = (struct d11txh *) pkt[0]->data;
plcp = (u8 *) (txh + 1);
WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
/* mark plcp to indicate ampdu */
WLC_SET_MIMO_PLCP_AMPDU(plcp);
BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
/* reset the mixed mode header durations */
if (txh->MModeLen) {
u16 mmodelen =
wlc_calc_lsig_len(wlc, rspec, ampdu_len);
brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
txh->MModeLen = cpu_to_le16(mmodelen);
preamble_type = WLC_MM_PREAMBLE;
preamble_type = BRCMS_MM_PREAMBLE;
}
if (txh->MModeFbrLen) {
u16 mmfbrlen =
wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len);
brcms_c_calc_lsig_len(wlc, rspec_fallback,
ampdu_len);
txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
fbr_preamble_type = WLC_MM_PREAMBLE;
fbr_preamble_type = BRCMS_MM_PREAMBLE;
}
/* set the preload length */
@ -776,19 +759,19 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
rts = (struct ieee80211_rts *)&txh->rts_frame;
if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
TXC_PREAMBLE_RTS_MAIN_SHORT)
rts_preamble_type = WLC_SHORT_PREAMBLE;
rts_preamble_type = BRCMS_SHORT_PREAMBLE;
if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
TXC_PREAMBLE_RTS_FB_SHORT)
rts_fbr_preamble_type = WLC_SHORT_PREAMBLE;
rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
durid =
wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec,
brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
rspec, rts_preamble_type,
preamble_type, ampdu_len,
true);
rts->duration = cpu_to_le16(durid);
durid = wlc_compute_rtscts_dur(wlc, use_cts,
durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
rts_rspec_fallback,
rspec_fallback,
rts_fbr_preamble_type,
@ -805,8 +788,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
if (fbr) {
mch |= TXC_AMPDU_FBR;
txh->MacTxControlHigh = cpu_to_le16(mch);
WLC_SET_MIMO_PLCP_AMPDU(plcp);
WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
}
BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
@ -819,7 +802,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
"TXFID_RATE_PROBE_MASK!?\n", __func__);
}
for (i = 0; i < count; i++)
wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1),
brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
ampdu->txpkt_weight);
}
@ -828,12 +811,12 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
}
void
wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
struct sk_buff *p, tx_status_t *txs)
brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
struct sk_buff *p, struct tx_status *txs)
{
scb_ampdu_t *scb_ampdu;
struct wlc_info *wlc = ampdu->wlc;
scb_ampdu_tid_ini_t *ini;
struct scb_ampdu *scb_ampdu;
struct brcms_c_info *wlc = ampdu->wlc;
struct scb_ampdu_tid_ini *ini;
u32 s1 = 0, s2 = 0;
struct ieee80211_tx_info *tx_info;
@ -861,31 +844,32 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
if (likely(scb)) {
scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
ini = SCB_AMPDU_INI(scb_ampdu, p->priority);
wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
} else {
/* loop through all pkts and free */
u8 queue = txs->frameid & TXFID_QUEUE_MASK;
d11txh_t *txh;
struct d11txh *txh;
u16 mcl;
while (p) {
tx_info = IEEE80211_SKB_CB(p);
txh = (d11txh_t *) p->data;
txh = (struct d11txh *) p->data;
mcl = le16_to_cpu(txh->MacTxControlLow);
bcm_pkt_buf_free_skb(p);
brcmu_pkt_buf_free_skb(p);
/* break out if last packet of ampdu */
if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
TXC_AMPDU_LAST)
break;
p = GETNEXTTXP(wlc, queue);
}
wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
}
wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini);
brcms_c_ampdu_txflowcontrol(wlc, scb_ampdu, ini);
}
static void
rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info,
tx_status_t *txs, u8 mcs)
brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
struct ieee80211_tx_info *tx_info,
struct tx_status *txs, u8 mcs)
{
struct ieee80211_tx_rate *txrate = tx_info->status.rates;
int i;
@ -900,15 +884,15 @@ rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info,
#define SHORTNAME "AMPDU status"
static void
wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
struct sk_buff *p, tx_status_t *txs,
brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
struct sk_buff *p, struct tx_status *txs,
u32 s1, u32 s2)
{
scb_ampdu_t *scb_ampdu;
struct wlc_info *wlc = ampdu->wlc;
scb_ampdu_tid_ini_t *ini;
struct scb_ampdu *scb_ampdu;
struct brcms_c_info *wlc = ampdu->wlc;
struct scb_ampdu_tid_ini *ini;
u8 bitmap[8], queue, tid;
d11txh_t *txh;
struct d11txh *txh;
u8 *plcp;
struct ieee80211_hdr *h;
u16 seq, start_seq = 0, bindex, index, mcl;
@ -974,9 +958,9 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
wlc->default_bss->chanspec));
} else {
if (supr_status != TX_STATUS_SUPR_FRAG)
wiphy_err(wiphy, "%s: wlc_ampdu_dotx"
"status:supr_status 0x%x\n",
__func__, supr_status);
wiphy_err(wiphy, "%s:"
"supr_status 0x%x\n",
__func__, supr_status);
}
/* no need to retry for badch; will fail again */
if (supr_status == TX_STATUS_SUPR_BADCH ||
@ -988,29 +972,29 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
/* if there were underflows, but pre-loading is not active,
notify rate adaptation.
*/
if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid])
> 0) {
if (brcms_c_ffpld_check_txfunfl(wlc,
prio2fifo[tid]) > 0) {
tx_error = true;
}
}
} else if (txs->phyerr) {
update_rate = false;
wiphy_err(wiphy, "wl%d: wlc_ampdu_dotxstatus: tx phy "
wiphy_err(wiphy, "wl%d: ampdu tx phy "
"error (0x%x)\n", wlc->pub->unit,
txs->phyerr);
if (WL_ERROR_ON()) {
bcm_prpkt("txpkt (AMPDU)", p);
wlc_print_txdesc((d11txh_t *) p->data);
brcmu_prpkt("txpkt (AMPDU)", p);
brcms_c_print_txdesc((struct d11txh *) p->data);
}
wlc_print_txstatus(txs);
brcms_c_print_txstatus(txs);
}
}
/* loop through all pkts and retry if not acked */
while (p) {
tx_info = IEEE80211_SKB_CB(p);
txh = (d11txh_t *) p->data;
txh = (struct d11txh *) p->data;
mcl = le16_to_cpu(txh->MacTxControlLow);
plcp = (u8 *) (txh + 1);
h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
@ -1037,7 +1021,8 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
/* ampdu_ack_len: number of acked aggregated frames */
/* ampdu_len: number of aggregated frames */
rate_status(wlc, tx_info, txs, mcs);
brcms_c_ampdu_rate_status(wlc, tx_info, txs,
mcs);
tx_info->flags |= IEEE80211_TX_STAT_ACK;
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
tx_info->status.ampdu_ack_len =
@ -1060,9 +1045,10 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
ini->txretry[index]++;
ini->tx_in_transit--;
/* Use high prededence for retransmit to give some punch */
/* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */
wlc_txq_enq(wlc, scb, p,
WLC_PRIO_TO_HI_PREC(tid));
/* brcms_c_txq_enq(wlc, scb, p,
* BRCMS_PRIO_TO_PREC(tid)); */
brcms_c_txq_enq(wlc, scb, p,
BRCMS_PRIO_TO_HI_PREC(tid));
} else {
/* Retry timeout */
ini->tx_in_transit--;
@ -1089,38 +1075,17 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
p = GETNEXTTXP(wlc, queue);
}
wlc_send_q(wlc);
brcms_c_send_q(wlc);
/* update rate state */
antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel);
antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
}
/* initialize the initiator code for tid */
static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu,
scb_ampdu_t *scb_ampdu,
u8 tid, bool override)
static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
{
scb_ampdu_tid_ini_t *ini;
/* check for per-tid control of ampdu */
if (!ampdu->ini_enable[tid]) {
wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
__func__, tid);
return NULL;
}
ini = SCB_AMPDU_INI(scb_ampdu, tid);
ini->tid = tid;
ini->scb = scb_ampdu->scb;
ini->magic = INI_MAGIC;
return ini;
}
static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on)
{
struct wlc_info *wlc = ampdu->wlc;
struct brcms_c_info *wlc = ampdu->wlc;
wlc->pub->_ampdu = false;
@ -1130,7 +1095,7 @@ static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on)
"nmode enabled\n", wlc->pub->unit);
return -ENOTSUPP;
}
if (!wlc_ampdu_cap(ampdu)) {
if (!brcms_c_ampdu_cap(ampdu)) {
wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
"ampdu capable\n", wlc->pub->unit);
return -ENOTSUPP;
@ -1141,15 +1106,15 @@ static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on)
return 0;
}
static bool wlc_ampdu_cap(struct ampdu_info *ampdu)
static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
{
if (WLC_PHY_11N_CAP(ampdu->wlc->band))
if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
return true;
else
return false;
}
static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
{
u32 rate, mcs;
@ -1170,34 +1135,35 @@ static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
}
}
void wlc_ampdu_macaddr_upd(struct wlc_info *wlc)
void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
{
char template[T_RAM_ACCESS_SZ * 2];
/* driver needs to write the ta in the template; ta is at offset 16 */
memset(template, 0, sizeof(template));
memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2),
template);
brcms_c_write_template_ram(wlc, (T_BA_TPL_BASE + 16),
(T_RAM_ACCESS_SZ * 2),
template);
}
bool wlc_aggregatable(struct wlc_info *wlc, u8 tid)
bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
{
return wlc->ampdu->ini_enable[tid];
}
void wlc_ampdu_shm_upd(struct ampdu_info *ampdu)
void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
{
struct wlc_info *wlc = ampdu->wlc;
struct brcms_c_info *wlc = ampdu->wlc;
/* Extend ucode internal watchdog timer to match larger received frames */
if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
IEEE80211_HT_MAX_AMPDU_64K) {
wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
brcms_c_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
brcms_c_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
} else {
wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
brcms_c_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
brcms_c_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
}
}
@ -1235,10 +1201,10 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a)
* When a remote party is no longer available for ampdu communication, any
* pending tx ampdu packets in the driver have to be flushed.
*/
void wlc_ampdu_flush(struct wlc_info *wlc,
void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
struct ieee80211_sta *sta, u16 tid)
{
struct wlc_txq_info *qi = wlc->pkt_queue;
struct brcms_txq_info *qi = wlc->pkt_queue;
struct pktq *pq = &qi->q;
int prec;
struct cb_del_ampdu_pars ampdu_pars;
@ -1246,8 +1212,8 @@ void wlc_ampdu_flush(struct wlc_info *wlc,
ampdu_pars.sta = sta;
ampdu_pars.tid = tid;
for (prec = 0; prec < pq->num_prec; prec++) {
bcm_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
(void *)&ampdu_pars);
}
wlc_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
}

View File

@ -14,24 +14,17 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _wlc_types_h_
#define _wlc_types_h_
#ifndef _BRCM_AMPDU_H_
#define _BRCM_AMPDU_H_
/* forward declarations */
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);
struct wlc_info;
struct wlc_hw_info;
struct wlc_if;
struct wl_if;
struct ampdu_info;
struct antsel_info;
struct bmac_pmq;
struct d11init;
#ifndef _hnddma_pub_
#define _hnddma_pub_
struct hnddma_pub;
#endif /* _hnddma_pub_ */
#endif /* _wlc_types_h_ */
#endif /* _BRCM_AMPDU_H_ */

View File

@ -14,40 +14,29 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <wlc_cfg.h>
#include <linux/slab.h>
#include <net/mac80211.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "types.h"
#include "bmac.h"
#include "main.h"
#include "phy_shim.h"
#include "antsel.h"
#include <bcmdefs.h>
#include <bcmutils.h>
#include <bcmnvram.h>
#include <aiutils.h>
#include <bcmdevs.h>
#include <sbhnddma.h>
#include <wlioctl.h>
#include "d11.h"
#include "wlc_rate.h"
#include "wlc_key.h"
#include "wlc_scb.h"
#include "wlc_pub.h"
#include "wl_dbg.h"
#include "phy/wlc_phy_hal.h"
#include "wlc_bmac.h"
#include "wlc_channel.h"
#include "wlc_main.h"
#include "wl_export.h"
#include "wlc_phy_shim.h"
#include "wlc_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 WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
#define WLC_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf)
#define WLC_ANTIDX_11N(ant) (((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant)))
#define WLC_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
#define WLC_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK)
#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 */
@ -62,11 +51,12 @@
#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */
/* static functions */
static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel);
static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id);
static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg);
static void wlc_antsel_init_cfg(struct antsel_info *asi,
wlc_antselcfg_t *antsel,
static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
struct brcms_antselcfg *antsel);
static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id);
static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg);
static void brcms_c_antsel_init_cfg(struct antsel_info *asi,
struct brcms_antselcfg *antsel,
bool auto_sel);
const u16 mimo_2x4_div_antselpat_tbl[] = {
@ -93,14 +83,14 @@ const u8 mimo_2x3_div_antselid_tbl[16] = {
0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */
};
struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc)
struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
{
struct antsel_info *asi;
asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
if (!asi) {
wiphy_err(wlc->wiphy, "wl%d: wlc_antsel_attach: out of mem\n",
wlc->pub->unit);
wiphy_err(wlc->wiphy, "wl%d: brcms_c_antsel_attach: out of "
"mem\n", wlc->pub->unit);
return NULL;
}
@ -129,7 +119,7 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc)
asi->antsel_avail = false;
} else {
asi->antsel_avail = false;
wiphy_err(wlc->wiphy, "wlc_antsel_attach: 2o3 "
wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
"board cfg invalid\n");
}
break;
@ -148,30 +138,30 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc)
}
/* Set the antenna selection type for the low driver */
wlc_bmac_antsel_type_set(wlc->hw, asi->antsel_type);
brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
/* Init (auto/manual) antenna selection */
wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true);
wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true);
brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
return asi;
}
void wlc_antsel_detach(struct antsel_info *asi)
void brcms_c_antsel_detach(struct antsel_info *asi)
{
kfree(asi);
}
void wlc_antsel_init(struct antsel_info *asi)
void brcms_c_antsel_init(struct antsel_info *asi)
{
if ((asi->antsel_type == ANTSEL_2x3) ||
(asi->antsel_type == ANTSEL_2x4))
wlc_antsel_cfgupd(asi, &asi->antcfg_11n);
brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
}
/* boardlevel antenna selection: init antenna selection structure */
static void
wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel,
brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
bool auto_sel)
{
if (asi->antsel_type == ANTSEL_2x3) {
@ -202,7 +192,7 @@ wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel,
}
void
wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
u8 antselid, u8 fbantselid, u8 *antcfg,
u8 *fbantcfg)
{
@ -222,8 +212,8 @@ wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
} else {
ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
*antcfg = wlc_antsel_id2antcfg(asi, antselid);
*fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid);
*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];
@ -234,7 +224,7 @@ wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
}
/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
{
u8 antselid = 0;
@ -253,7 +243,7 @@ u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
}
/* boardlevel antenna selection: convert id to ant_cfg */
static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id)
static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
{
u8 antcfg = ANT_SELCFG_DEF_2x2;
@ -272,9 +262,9 @@ static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id)
}
/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */
static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
{
u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg));
u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
u16 mimo_antsel = 0;
if (asi->antsel_type == ANTSEL_2x4) {
@ -292,9 +282,10 @@ static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
}
/* boardlevel antenna selection: ucode interface control */
static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel)
static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
struct brcms_antselcfg *antsel)
{
struct wlc_info *wlc = asi->wlc;
struct brcms_c_info *wlc = asi->wlc;
u8 ant_cfg;
u16 mimo_antsel;
@ -302,8 +293,8 @@ static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel)
* (aka default TX)
*/
ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg);
wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
brcms_c_write_shm(wlc, 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;
@ -311,8 +302,8 @@ static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel)
* (aka default RX)
*/
ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg);
wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
brcms_c_write_shm(wlc, 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;

View File

@ -14,16 +14,16 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _wlc_antsel_h_
#define _wlc_antsel_h_
#ifndef _BRCM_ANTSEL_H_
#define _BRCM_ANTSEL_H_
extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc);
extern void wlc_antsel_detach(struct antsel_info *asi);
extern void wlc_antsel_init(struct antsel_info *asi);
extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
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 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
#endif /* _wlc_antsel_h_ */
#endif /* _BRCM_ANTSEL_H_ */

View File

@ -1,936 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/crc-ccitt.h>
#include <bcmdefs.h>
#include <bcmdevs.h>
#include <bcmutils.h>
#include <aiutils.h>
#include <hndsoc.h>
#include <sbchipc.h>
#include <bcmotp.h>
/*
* There are two different OTP controllers so far:
* 1. new IPX OTP controller: chipc 21, >=23
* 2. older HND OTP controller: chipc 12, 17, 22
*
* Define BCMHNDOTP to include support for the HND OTP controller.
* Define BCMIPXOTP to include support for the IPX OTP controller.
*
* NOTE 1: More than one may be defined
* NOTE 2: If none are defined, the default is to include them all.
*/
#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
#define BCMHNDOTP 1
#define BCMIPXOTP 1
#endif
#define OTPTYPE_HND(ccrev) ((ccrev) < 21 || (ccrev) == 22)
#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
#define OTPP_TRIES 10000000 /* # of tries for OTPP */
#ifdef BCMIPXOTP
#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
#endif
/* OTP common function type */
typedef int (*otp_status_t) (void *oh);
typedef int (*otp_size_t) (void *oh);
typedef void *(*otp_init_t) (si_t *sih);
typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data,
uint *wlen);
typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
/* OTP function struct */
typedef struct otp_fn_s {
otp_size_t size;
otp_read_bit_t read_bit;
otp_init_t init;
otp_read_region_t read_region;
otp_nvread_t nvread;
otp_status_t status;
} otp_fn_t;
typedef struct {
uint ccrev; /* chipc revision */
otp_fn_t *fn; /* OTP functions */
si_t *sih; /* Saved sb handle */
#ifdef BCMIPXOTP
/* 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 */
#endif /* BCMIPXOTP */
#ifdef BCMHNDOTP
/* HND OTP section */
uint size; /* Size of otp in bytes */
uint hwprot; /* Hardware protection bits */
uint signvalid; /* Signature valid bits */
int boundary; /* hw/sw boundary */
#endif /* BCMHNDOTP */
} otpinfo_t;
static otpinfo_t otpinfo;
/*
* IPX OTP Code
*
* Exported functions:
* ipxotp_status()
* ipxotp_size()
* ipxotp_init()
* ipxotp_read_bit()
* ipxotp_read_region()
* ipxotp_nvread()
*
*/
#ifdef BCMIPXOTP
#define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
/* 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 int ipxotp_status(void *oh)
{
otpinfo_t *oi = (otpinfo_t *) oh;
return (int)(oi->status);
}
/* Return size in bytes */
static int ipxotp_size(void *oh)
{
otpinfo_t *oi = (otpinfo_t *) oh;
return (int)oi->wsize * 2;
}
static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
{
otpinfo_t *oi;
oi = (otpinfo_t *) oh;
return R_REG(&cc->sromotp[wn]);
}
static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
{
otpinfo_t *oi = (otpinfo_t *) oh;
uint k, row, col;
u32 otpp, st;
row = off / oi->cols;
col = off % oi->cols;
otpp = OTPP_START_BUSY |
((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
((col << OTPP_COL_SHIFT) & OTPP_COL_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 0xffff;
}
if (st & OTPP_READERR) {
return 0xffff;
}
st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
return (int)st;
}
/* 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(si_t *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(otpinfo_t *oi, chipcregs_t *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 void *ipxotp_init(si_t *sih)
{
uint idx;
chipcregs_t *cc;
otpinfo_t *oi;
/* Make sure we're running IPX OTP */
if (!OTPTYPE_IPX(sih->ccrev))
return NULL;
/* Make sure OTP is not disabled */
if (ai_is_otp_disabled(sih))
return NULL;
/* Make sure OTP is powered up */
if (!ai_is_otp_powered(sih))
return NULL;
oi = &otpinfo;
/* Check for otp size */
switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
case 0:
/* Nothing there */
return NULL;
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 NULL;
}
/* Retrieve OTP region info */
idx = ai_coreidx(sih);
cc = ai_setcoreidx(sih, SI_CC_IDX);
_ipxotp_init(oi, cc);
ai_setcoreidx(sih, idx);
return (void *)oi;
}
static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
{
otpinfo_t *oi = (otpinfo_t *) oh;
uint idx;
chipcregs_t *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(oh, cc, base + i);
ai_setcoreidx(oi->sih, idx);
*wlen = sz;
return 0;
}
static int ipxotp_nvread(void *oh, char *data, uint *len)
{
return -ENOTSUPP;
}
static otp_fn_t ipxotp_fn = {
(otp_size_t) ipxotp_size,
(otp_read_bit_t) ipxotp_read_bit,
(otp_init_t) ipxotp_init,
(otp_read_region_t) ipxotp_read_region,
(otp_nvread_t) ipxotp_nvread,
(otp_status_t) ipxotp_status
};
#endif /* BCMIPXOTP */
/*
* HND OTP Code
*
* Exported functions:
* hndotp_status()
* hndotp_size()
* hndotp_init()
* hndotp_read_bit()
* hndotp_read_region()
* hndotp_nvread()
*
*/
#ifdef BCMHNDOTP
/* Fields in otpstatus */
#define OTPS_PROGFAIL 0x80000000
#define OTPS_PROTECT 0x00000007
#define OTPS_HW_PROTECT 0x00000001
#define OTPS_SW_PROTECT 0x00000002
#define OTPS_CID_PROTECT 0x00000004
#define OTPS_RCEV_MSK 0x00003f00
#define OTPS_RCEV_SHIFT 8
/* Fields in the otpcontrol register */
#define OTPC_RECWAIT 0xff000000
#define OTPC_PROGWAIT 0x00ffff00
#define OTPC_PRW_SHIFT 8
#define OTPC_MAXFAIL 0x00000038
#define OTPC_VSEL 0x00000006
#define OTPC_SELVL 0x00000001
/* OTP regions (Word offsets from otp size) */
#define OTP_SWLIM_OFF (-4)
#define OTP_CIDBASE_OFF 0
#define OTP_CIDLIM_OFF 4
/* Predefined OTP words (Word offset from otp size) */
#define OTP_BOUNDARY_OFF (-4)
#define OTP_HWSIGN_OFF (-3)
#define OTP_SWSIGN_OFF (-2)
#define OTP_CIDSIGN_OFF (-1)
#define OTP_CID_OFF 0
#define OTP_PKG_OFF 1
#define OTP_FID_OFF 2
#define OTP_RSV_OFF 3
#define OTP_LIM_OFF 4
#define OTP_RD_OFF 4 /* Redundancy row starts here */
#define OTP_RC0_OFF 28 /* Redundancy control word 1 */
#define OTP_RC1_OFF 32 /* Redundancy control word 2 */
#define OTP_RC_LIM_OFF 36 /* Redundancy control word end */
#define OTP_HW_REGION OTPS_HW_PROTECT
#define OTP_SW_REGION OTPS_SW_PROTECT
#define OTP_CID_REGION OTPS_CID_PROTECT
#if OTP_HW_REGION != OTP_HW_RGN
#error "incompatible OTP_HW_RGN"
#endif
#if OTP_SW_REGION != OTP_SW_RGN
#error "incompatible OTP_SW_RGN"
#endif
#if OTP_CID_REGION != OTP_CI_RGN
#error "incompatible OTP_CI_RGN"
#endif
/* Redundancy entry definitions */
#define OTP_RCE_ROW_SZ 6
#define OTP_RCE_SIGN_MASK 0x7fff
#define OTP_RCE_ROW_MASK 0x3f
#define OTP_RCE_BITS 21
#define OTP_RCE_SIGN_SZ 15
#define OTP_RCE_BIT0 1
#define OTP_WPR 4
#define OTP_SIGNATURE 0x578a
#define OTP_MAGIC 0x4e56
static int hndotp_status(void *oh)
{
otpinfo_t *oi = (otpinfo_t *) oh;
return (int)(oi->hwprot | oi->signvalid);
}
static int hndotp_size(void *oh)
{
otpinfo_t *oi = (otpinfo_t *) oh;
return (int)(oi->size);
}
static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn)
{
volatile u16 *ptr;
ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
return R_REG(&ptr[wn]);
}
static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff)
{
otpinfo_t *oi = (otpinfo_t *) oh;
volatile u16 *ptr;
ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
return R_REG(&ptr[(oi->size / 2) + woff]);
}
static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx)
{
uint k, row, col;
u32 otpp, st;
row = idx / 65;
col = idx % 65;
otpp = OTPP_START_BUSY | OTPP_READ |
((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK);
W_REG(&cc->otpprog, otpp);
st = R_REG(&cc->otpprog);
for (k = 0;
((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES);
k++)
st = R_REG(&cc->otpprog);
if (k >= OTPP_TRIES) {
return 0xffff;
}
if (st & OTPP_READERR) {
return 0xffff;
}
st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
return (u16) st;
}
static void *hndotp_init(si_t *sih)
{
uint idx;
chipcregs_t *cc;
otpinfo_t *oi;
u32 cap = 0, clkdiv, otpdiv = 0;
void *ret = NULL;
oi = &otpinfo;
idx = ai_coreidx(sih);
/* Check for otp */
cc = ai_setcoreidx(sih, SI_CC_IDX);
if (cc != NULL) {
cap = R_REG(&cc->capabilities);
if ((cap & CC_CAP_OTPSIZE) == 0) {
/* Nothing there */
goto out;
}
if (!((oi->ccrev == 12) || (oi->ccrev == 17)
|| (oi->ccrev == 22)))
return NULL;
/* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
* 8 row (64 bytes) smaller
*/
oi->size =
1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT)
+ CC_CAP_OTPSIZE_BASE);
if (oi->ccrev >= 18)
oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2);
oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT);
oi->boundary = -1;
/* Check the region signature */
if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) {
oi->signvalid |= OTP_HW_REGION;
oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF);
}
if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE)
oi->signvalid |= OTP_SW_REGION;
if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE)
oi->signvalid |= OTP_CID_REGION;
/* Set OTP clkdiv for stability */
if (oi->ccrev == 22)
otpdiv = 12;
if (otpdiv) {
clkdiv = R_REG(&cc->clkdiv);
clkdiv =
(clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT);
W_REG(&cc->clkdiv, clkdiv);
}
udelay(10);
ret = (void *)oi;
}
out: /* All done */
ai_setcoreidx(sih, idx);
return ret;
}
static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen)
{
otpinfo_t *oi = (otpinfo_t *) oh;
u32 idx, st;
chipcregs_t *cc;
int i;
if (region != OTP_HW_REGION) {
/*
* Only support HW region
* (no active chips use HND OTP SW region)
* */
return -ENOTSUPP;
}
/* Region empty? */
st = oi->hwprot | oi->signvalid;
if ((st & region) == 0)
return -ENODATA;
*wlen =
((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2;
idx = ai_coreidx(oi->sih);
cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
for (i = 0; i < (int)*wlen; i++)
data[i] = hndotp_otpr(oh, cc, i);
ai_setcoreidx(oi->sih, idx);
return 0;
}
static int hndotp_nvread(void *oh, char *data, uint *len)
{
int rc = 0;
otpinfo_t *oi = (otpinfo_t *) oh;
u32 base, bound, lim = 0, st;
int i, chunk, gchunks, tsz = 0;
u32 idx;
chipcregs_t *cc;
uint offset;
u16 *rawotp = NULL;
/* save the orig core */
idx = ai_coreidx(oi->sih);
cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
st = hndotp_status(oh);
if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) {
rc = -1;
goto out;
}
/* Read the whole otp so we can easily manipulate it */
lim = hndotp_size(oh);
rawotp = kmalloc(lim, GFP_ATOMIC);
if (rawotp == NULL) {
rc = -2;
goto out;
}
for (i = 0; i < (int)(lim / 2); i++)
rawotp[i] = hndotp_otpr(oh, cc, i);
if ((st & OTP_HW_REGION) == 0) {
/* This could be a programming failure in the first
* chunk followed by one or more good chunks
*/
for (i = 0; i < (int)(lim / 2); i++)
if (rawotp[i] == OTP_MAGIC)
break;
if (i < (int)(lim / 2)) {
base = i;
bound = (i * 2) + rawotp[i + 1];
} else {
rc = -3;
goto out;
}
} else {
bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF];
/* There are two cases: 1) The whole otp is used as nvram
* and 2) There is a hardware header followed by nvram.
*/
if (rawotp[0] == OTP_MAGIC) {
base = 0;
} else
base = bound;
}
/* Find and copy the data */
chunk = 0;
gchunks = 0;
i = base / 2;
offset = 0;
while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) {
int dsz, rsz = rawotp[i + 1];
if (((i * 2) + rsz) >= (int)lim) {
/* Bad length, try to find another chunk anyway */
rsz = 6;
}
if (crc_ccitt(CRC16_INIT_VALUE, (u8 *) &rawotp[i], rsz) ==
CRC16_GOOD_VALUE) {
/* Good crc, copy the vars */
gchunks++;
dsz = rsz - 6;
tsz += dsz;
if (offset + dsz >= *len) {
goto out;
}
memcpy(&data[offset], &rawotp[i + 2], dsz);
offset += dsz;
/* Remove extra null characters at the end */
while (offset > 1 &&
data[offset - 1] == 0 && data[offset - 2] == 0)
offset--;
i += rsz / 2;
} else {
/* bad length or crc didn't check, try to find the next set */
if (rawotp[i + (rsz / 2)] == OTP_MAGIC) {
/* Assume length is good */
i += rsz / 2;
} else {
while (++i < (int)(lim / 2))
if (rawotp[i] == OTP_MAGIC)
break;
}
}
chunk++;
}
*len = offset;
out:
kfree(rawotp);
ai_setcoreidx(oi->sih, idx);
return rc;
}
static otp_fn_t hndotp_fn = {
(otp_size_t) hndotp_size,
(otp_read_bit_t) hndotp_read_bit,
(otp_init_t) hndotp_init,
(otp_read_region_t) hndotp_read_region,
(otp_nvread_t) hndotp_nvread,
(otp_status_t) hndotp_status
};
#endif /* BCMHNDOTP */
/*
* Common Code: Compiled for IPX / HND / AUTO
* otp_status()
* otp_size()
* otp_read_bit()
* otp_init()
* otp_read_region()
* otp_nvread()
*/
int otp_status(void *oh)
{
otpinfo_t *oi = (otpinfo_t *) oh;
return oi->fn->status(oh);
}
int otp_size(void *oh)
{
otpinfo_t *oi = (otpinfo_t *) oh;
return oi->fn->size(oh);
}
u16 otp_read_bit(void *oh, uint offset)
{
otpinfo_t *oi = (otpinfo_t *) oh;
uint idx = ai_coreidx(oi->sih);
chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
ai_setcoreidx(oi->sih, idx);
return readBit;
}
void *otp_init(si_t *sih)
{
otpinfo_t *oi;
void *ret = NULL;
oi = &otpinfo;
memset(oi, 0, sizeof(otpinfo_t));
oi->ccrev = sih->ccrev;
#ifdef BCMIPXOTP
if (OTPTYPE_IPX(oi->ccrev))
oi->fn = &ipxotp_fn;
#endif
#ifdef BCMHNDOTP
if (OTPTYPE_HND(oi->ccrev))
oi->fn = &hndotp_fn;
#endif
if (oi->fn == NULL) {
return NULL;
}
oi->sih = sih;
ret = (oi->fn->init) (sih);
return ret;
}
int
otp_read_region(si_t *sih, int region, u16 *data,
uint *wlen) {
bool wasup = false;
void *oh;
int err = 0;
wasup = ai_is_otp_powered(sih);
if (!wasup)
ai_otp_power(sih, true);
if (!ai_is_otp_powered(sih) || ai_is_otp_disabled(sih)) {
err = -EPERM;
goto out;
}
oh = otp_init(sih);
if (oh == NULL) {
err = -EBADE;
goto out;
}
err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen);
out:
if (!wasup)
ai_otp_power(sih, false);
return err;
}
int otp_nvread(void *oh, char *data, uint *len)
{
otpinfo_t *oi = (otpinfo_t *) oh;
return oi->fn->nvread(oh, data, len);
}

View File

@ -1,714 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/etherdevice.h>
#include <bcmdefs.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <stdarg.h>
#include <bcmutils.h>
#include <hndsoc.h>
#include <sbchipc.h>
#include <bcmdevs.h>
#include <pcicfg.h>
#include <aiutils.h>
#include <bcmsrom.h>
#include <bcmsrom_tbl.h>
#include <bcmnvram.h>
#include <bcmotp.h>
#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
(((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
((u8 *)curmap + PCI_BAR0_SPROM_OFFSET))
#if defined(BCMDBG)
#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
#endif
typedef struct varbuf {
char *base; /* pointer to buffer base */
char *buf; /* pointer to current position */
unsigned int size; /* current (residual) size in bytes */
} varbuf_t;
extern char *_vars;
extern uint _varsz;
static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count);
static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b);
static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count);
static int initvars_flash_si(si_t *sih, char **vars, uint *count);
static int sprom_read_pci(si_t *sih, u16 *sprom,
uint wordoff, u16 *buf, uint nwords, bool check_crc);
#if defined(BCMNVRAMR)
static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz);
#endif
static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
uint wordoff, u16 data);
static int initvars_table(char *start, char *end,
char **vars, uint *count);
static int initvars_flash(si_t *sih, char **vp,
uint len);
/* Initialization of varbuf structure */
static void varbuf_init(varbuf_t *b, char *buf, uint size)
{
b->size = size;
b->base = b->buf = buf;
}
/* append a null terminated var=value string */
static int varbuf_append(varbuf_t *b, const char *fmt, ...)
{
va_list ap;
int r;
size_t len;
char *s;
if (b->size < 2)
return 0;
va_start(ap, fmt);
r = vsnprintf(b->buf, b->size, fmt, ap);
va_end(ap);
/* C99 snprintf behavior returns r >= size on overflow,
* others return -1 on overflow.
* All return -1 on format error.
* We need to leave room for 2 null terminations, one for the current var
* string, and one for final null of the var table. So check that the
* strlen written, r, leaves room for 2 chars.
*/
if ((r == -1) || (r > (int)(b->size - 2))) {
b->size = 0;
return 0;
}
/* Remove any earlier occurrence of the same variable */
s = strchr(b->buf, '=');
if (s != NULL) {
len = (size_t) (s - b->buf);
for (s = b->base; s < b->buf;) {
if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') {
len = strlen(s) + 1;
memmove(s, (s + len),
((b->buf + r + 1) - (s + len)));
b->buf -= len;
b->size += (unsigned int)len;
break;
}
while (*s++)
;
}
}
/* skip over this string's null termination */
r++;
b->size -= r;
b->buf += r;
return r;
}
/*
* Initialize local vars from the right source for this platform.
* Return 0 on success, nonzero on error.
*/
int srom_var_init(si_t *sih, uint bustype, void *curmap,
char **vars, uint *count)
{
uint len;
len = 0;
if (vars == NULL || count == NULL)
return 0;
*vars = NULL;
*count = 0;
switch (bustype) {
case SI_BUS:
case JTAG_BUS:
return initvars_srom_si(sih, curmap, vars, count);
case PCI_BUS:
if (curmap == NULL)
return -1;
return initvars_srom_pci(sih, curmap, vars, count);
default:
break;
}
return -1;
}
/* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
* not in the bus cores.
*/
static u16
srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
uint wordoff, u16 data)
{
chipcregs_t *cc = (chipcregs_t *) ccregs;
uint wait_cnt = 1000;
if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) {
W_REG(&cc->sromaddress, wordoff * 2);
if (cmd == SRC_OP_WRITE)
W_REG(&cc->sromdata, data);
}
W_REG(&cc->sromcontrol, SRC_START | cmd);
while (wait_cnt--) {
if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0)
break;
}
if (!wait_cnt) {
return 0xffff;
}
if (cmd == SRC_OP_READ)
return (u16) R_REG(&cc->sromdata);
else
return 0xffff;
}
static inline void ltoh16_buf(u16 *buf, unsigned int size)
{
for (size /= 2; size; size--)
*(buf + size) = le16_to_cpu(*(buf + size));
}
static inline void htol16_buf(u16 *buf, unsigned int size)
{
for (size /= 2; size; size--)
*(buf + size) = cpu_to_le16(*(buf + size));
}
/*
* Read in and validate sprom.
* Return 0 on success, nonzero on error.
*/
static int
sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff,
u16 *buf, uint nwords, bool check_crc)
{
int err = 0;
uint i;
void *ccregs = NULL;
/* read the sprom */
for (i = 0; i < nwords; i++) {
if (sih->ccrev > 31 && ISSIM_ENAB(sih)) {
/* use indirect since direct is too slow on QT */
if ((sih->cccaps & CC_CAP_SROM) == 0)
return 1;
ccregs = (void *)((u8 *) sprom - CC_SROM_OTP);
buf[i] =
srom_cc_cmd(sih, ccregs, SRC_OP_READ,
wordoff + i, 0);
} else {
if (ISSIM_ENAB(sih))
buf[i] = R_REG(&sprom[wordoff + i]);
buf[i] = R_REG(&sprom[wordoff + i]);
}
}
/* bypass crc checking for simulation to allow srom hack */
if (ISSIM_ENAB(sih))
return err;
if (check_crc) {
if (buf[0] == 0xffff) {
/* The hardware thinks that an srom that starts with 0xffff
* is blank, regardless of the rest of the content, so declare
* it bad.
*/
return 1;
}
/* fixup the endianness so crc8 will pass */
htol16_buf(buf, nwords * 2);
if (bcm_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) !=
CRC8_GOOD_VALUE) {
/* DBG only pci always read srom4 first, then srom8/9 */
err = 1;
}
/* now correct the endianness of the byte array */
ltoh16_buf(buf, nwords * 2);
}
return err;
}
#if defined(BCMNVRAMR)
static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz)
{
u8 *otp;
uint sz = OTP_SZ_MAX / 2; /* size in words */
int err = 0;
otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
if (otp == NULL) {
return -EBADE;
}
err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
memcpy(buf, otp, bufsz);
kfree(otp);
/* Check CRC */
if (buf[0] == 0xffff) {
/* The hardware thinks that an srom that starts with 0xffff
* is blank, regardless of the rest of the content, so declare
* it bad.
*/
return 1;
}
/* fixup the endianness so crc8 will pass */
htol16_buf(buf, bufsz);
if (bcm_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) !=
CRC8_GOOD_VALUE) {
err = 1;
}
/* now correct the endianness of the byte array */
ltoh16_buf(buf, bufsz);
return err;
}
#endif /* defined(BCMNVRAMR) */
/*
* Create variable table from memory.
* Return 0 on success, nonzero on error.
*/
static int initvars_table(char *start, char *end,
char **vars, uint *count)
{
int c = (int)(end - start);
/* do it only when there is more than just the null string */
if (c > 1) {
char *vp = kmalloc(c, GFP_ATOMIC);
if (!vp)
return -ENOMEM;
memcpy(vp, start, c);
*vars = vp;
*count = c;
} else {
*vars = NULL;
*count = 0;
}
return 0;
}
/*
* Find variables with <devpath> from flash. 'base' points to the beginning
* of the table upon enter and to the end of the table upon exit when success.
* Return 0 on success, nonzero on error.
*/
static int initvars_flash(si_t *sih, char **base, uint len)
{
char *vp = *base;
char *flash;
int err;
char *s;
uint l, dl, copy_len;
char devpath[SI_DEVPATH_BUFSZ];
/* allocate memory and read in flash */
flash = kmalloc(NVRAM_SPACE, GFP_ATOMIC);
if (!flash)
return -ENOMEM;
err = nvram_getall(flash, NVRAM_SPACE);
if (err)
goto exit;
ai_devpath(sih, devpath, sizeof(devpath));
/* grab vars with the <devpath> prefix in name */
dl = strlen(devpath);
for (s = flash; s && *s; s += l + 1) {
l = strlen(s);
/* skip non-matching variable */
if (strncmp(s, devpath, dl))
continue;
/* is there enough room to copy? */
copy_len = l - dl + 1;
if (len < copy_len) {
err = -EOVERFLOW;
goto exit;
}
/* no prefix, just the name=value */
strncpy(vp, &s[dl], copy_len);
vp += copy_len;
len -= copy_len;
}
/* add null string as terminator */
if (len < 1) {
err = -EOVERFLOW;
goto exit;
}
*vp++ = '\0';
*base = vp;
exit: kfree(flash);
return err;
}
/*
* Initialize nonvolatile variable table from flash.
* Return 0 on success, nonzero on error.
*/
static int initvars_flash_si(si_t *sih, char **vars, uint *count)
{
char *vp, *base;
int err;
base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
if (!vp)
return -ENOMEM;
err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
if (err == 0)
err = initvars_table(base, vp, vars, count);
kfree(base);
return err;
}
/* Parse SROM and create name=value pairs. 'srom' points to
* the SROM word array. 'off' specifies the offset of the
* first word 'srom' points to, which should be either 0 or
* SROM3_SWRG_OFF (full SROM or software region).
*/
static uint mask_shift(u16 mask)
{
uint i;
for (i = 0; i < (sizeof(mask) << 3); i++) {
if (mask & (1 << i))
return i;
}
return 0;
}
static uint mask_width(u16 mask)
{
int i;
for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
if (mask & (1 << i))
return (uint) (i - mask_shift(mask) + 1);
}
return 0;
}
static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b)
{
u16 w;
u32 val;
const sromvar_t *srv;
uint width;
uint flags;
u32 sr = (1 << sromrev);
varbuf_append(b, "sromrev=%d", sromrev);
for (srv = pci_sromvars; srv->name != NULL; srv++) {
const char *name;
if ((srv->revmask & sr) == 0)
continue;
if (srv->off < off)
continue;
flags = srv->flags;
name = srv->name;
/* This entry is for mfgc only. Don't generate param for it, */
if (flags & SRFL_NOVAR)
continue;
if (flags & SRFL_ETHADDR) {
u8 ea[ETH_ALEN];
ea[0] = (srom[srv->off - off] >> 8) & 0xff;
ea[1] = srom[srv->off - off] & 0xff;
ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
ea[3] = srom[srv->off + 1 - off] & 0xff;
ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
ea[5] = srom[srv->off + 2 - off] & 0xff;
varbuf_append(b, "%s=%pM", name, ea);
} else {
w = srom[srv->off - off];
val = (w & srv->mask) >> mask_shift(srv->mask);
width = mask_width(srv->mask);
while (srv->flags & SRFL_MORE) {
srv++;
if (srv->off == 0 || srv->off < off)
continue;
w = srom[srv->off - off];
val +=
((w & srv->mask) >> mask_shift(srv->
mask)) <<
width;
width += mask_width(srv->mask);
}
if ((flags & SRFL_NOFFS)
&& ((int)val == (1 << width) - 1))
continue;
if (flags & SRFL_CCODE) {
if (val == 0)
varbuf_append(b, "ccode=");
else
varbuf_append(b, "ccode=%c%c",
(val >> 8), (val & 0xff));
}
/* LED Powersave duty cycle has to be scaled:
*(oncount >> 24) (offcount >> 8)
*/
else if (flags & SRFL_LEDDC) {
u32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */
(((val & 0xff)) << 8); /* offcount */
varbuf_append(b, "leddc=%d", w32);
} else if (flags & SRFL_PRHEX)
varbuf_append(b, "%s=0x%x", name, val);
else if ((flags & SRFL_PRSIGN)
&& (val & (1 << (width - 1))))
varbuf_append(b, "%s=%d", name,
(int)(val | (~0 << width)));
else
varbuf_append(b, "%s=%u", name, val);
}
}
if (sromrev >= 4) {
/* Do per-path variables */
uint p, pb, psz;
if (sromrev >= 8) {
pb = SROM8_PATH0;
psz = SROM8_PATH1 - SROM8_PATH0;
} else {
pb = SROM4_PATH0;
psz = SROM4_PATH1 - SROM4_PATH0;
}
for (p = 0; p < MAX_PATH_SROM; p++) {
for (srv = perpath_pci_sromvars; srv->name != NULL;
srv++) {
if ((srv->revmask & sr) == 0)
continue;
if (pb + srv->off < off)
continue;
/* This entry is for mfgc only. Don't generate param for it, */
if (srv->flags & SRFL_NOVAR)
continue;
w = srom[pb + srv->off - off];
val = (w & srv->mask) >> mask_shift(srv->mask);
width = mask_width(srv->mask);
/* Cheating: no per-path var is more than 1 word */
if ((srv->flags & SRFL_NOFFS)
&& ((int)val == (1 << width) - 1))
continue;
if (srv->flags & SRFL_PRHEX)
varbuf_append(b, "%s%d=0x%x", srv->name,
p, val);
else
varbuf_append(b, "%s%d=%d", srv->name,
p, val);
}
pb += psz;
}
}
}
/*
* Initialize nonvolatile variable table from sprom.
* Return 0 on success, nonzero on error.
*/
static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count)
{
u16 *srom, *sromwindow;
u8 sromrev = 0;
u32 sr;
varbuf_t b;
char *vp, *base = NULL;
bool flash = false;
int err = 0;
/*
* Apply CRC over SROM content regardless SROM is present or not,
* and use variable <devpath>sromrev's existence in flash to decide
* if we should return an error when CRC fails or read SROM variables
* from flash.
*/
srom = kmalloc(SROM_MAX, GFP_ATOMIC);
if (!srom)
return -2;
sromwindow = (u16 *) SROM_OFFSET(sih);
if (ai_is_sprom_available(sih)) {
err =
sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS,
true);
if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
(((sih->buscoretype == PCIE_CORE_ID)
&& (sih->buscorerev >= 6))
|| ((sih->buscoretype == PCI_CORE_ID)
&& (sih->buscorerev >= 0xe)))) {
/* sromrev >= 4, read more */
err =
sprom_read_pci(sih, sromwindow, 0, srom,
SROM4_WORDS, true);
sromrev = srom[SROM4_CRCREV] & 0xff;
} else if (err == 0) {
/* srom is good and is rev < 4 */
/* top word of sprom contains version and crc8 */
sromrev = srom[SROM_CRCREV] & 0xff;
/* bcm4401 sroms misprogrammed */
if (sromrev == 0x10)
sromrev = 1;
}
}
#if defined(BCMNVRAMR)
/* Use OTP if SPROM not available */
else {
err = otp_read_pci(sih, srom, SROM_MAX);
if (err == 0)
/* OTP only contain SROM rev8/rev9 for now */
sromrev = srom[SROM4_CRCREV] & 0xff;
else
err = 1;
}
#else
else
err = 1;
#endif
/*
* We want internal/wltest driver to come up with default
* sromvars so we can program a blank SPROM/OTP.
*/
if (err) {
char *value;
u32 val;
val = 0;
value = ai_getdevpathvar(sih, "sromrev");
if (value) {
sromrev = (u8) simple_strtoul(value, NULL, 0);
flash = true;
goto varscont;
}
value = ai_getnvramflvar(sih, "sromrev");
if (value) {
err = 0;
goto errout;
}
{
err = -1;
goto errout;
}
}
varscont:
/* Bitmask for the sromrev */
sr = 1 << sromrev;
/* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */
if ((sr & 0x33e) == 0) {
err = -2;
goto errout;
}
base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
if (!vp) {
err = -2;
goto errout;
}
/* read variables from flash */
if (flash) {
err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
if (err)
goto errout;
goto varsdone;
}
varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
/* parse SROM into name=value pairs. */
_initvars_srom_pci(sromrev, srom, 0, &b);
/* final nullbyte terminator */
vp = b.buf;
*vp++ = '\0';
varsdone:
err = initvars_table(base, vp, vars, count);
errout:
if (base)
kfree(base);
kfree(srom);
return err;
}
static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz)
{
/* Search flash nvram section for srom variables */
return initvars_flash_si(sih, vars, varsz);
}

View File

@ -0,0 +1,174 @@
/*
* 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_BOTTOM_MAC_H_
#define _BRCM_BOTTOM_MAC_H_
#include <brcmu_wifi.h>
#include "types.h"
/* dup state between BMAC(struct brcms_hardware) and HIGH(struct brcms_c_info)
driver */
struct brcms_b_state {
u32 machwcap; /* mac hw capibility */
u32 preamble_ovr; /* preamble override */
};
enum {
IOV_BMAC_DIAG,
IOV_BMAC_SBGPIOTIMERVAL,
IOV_BMAC_SBGPIOOUT,
IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */
IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */
IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */
IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */
IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */
IOV_BMAC_OTPDUMP,
IOV_BMAC_OTPSTAT,
IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */
IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */
IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */
IOV_BMAC_PCIELCREG, /* PCIE LCREG */
IOV_BMAC_SBGPIOTIMERMASK,
IOV_BMAC_RFDISABLEDLY,
IOV_BMAC_PCIEREG, /* PCIE REG */
IOV_BMAC_PCICFGREG, /* PCI Config register */
IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */
IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */
IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */
IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */
IOV_BMAC_DMALPBK,
IOV_BMAC_CCREG,
IOV_BMAC_COREREG,
IOV_BMAC_SDCIS,
IOV_BMAC_SDIO_DRIVE,
IOV_BMAC_OTPW,
IOV_BMAC_NVOTPW,
IOV_BMAC_SROM,
IOV_BMAC_SRCRC,
IOV_BMAC_CIS_SOURCE,
IOV_BMAC_CISVAR,
IOV_BMAC_OTPLOCK,
IOV_BMAC_OTP_CHIPID,
IOV_BMAC_CUSTOMVAR1,
IOV_BMAC_BOARDFLAGS,
IOV_BMAC_BOARDFLAGS2,
IOV_BMAC_WPSLED,
IOV_BMAC_NVRAM_SOURCE,
IOV_BMAC_OTP_RAW_READ,
IOV_BMAC_LAST
};
extern int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device,
uint unit, bool piomode, void *regsva, uint bustype,
void *btparam);
extern int brcms_b_detach(struct brcms_c_info *wlc);
extern void brcms_b_watchdog(void *arg);
/* up/down, reset, clk */
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);
#define brcms_b_copyfrom_shm(wlc_hw, offset, buf, len) \
brcms_b_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
#define brcms_b_copyto_shm(wlc_hw, offset, buf, len) \
brcms_b_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
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_phy_reset(struct brcms_hardware *wlc_hw);
extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
extern void brcms_b_reset(struct brcms_hardware *wlc_hw);
extern void brcms_b_init(struct brcms_hardware *wlc_hw, chanspec_t chanspec,
bool mute);
extern int brcms_b_up_prep(struct brcms_hardware *wlc_hw);
extern int brcms_b_up_finish(struct brcms_hardware *wlc_hw);
extern int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw);
extern int brcms_b_down_finish(struct brcms_hardware *wlc_hw);
extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
/* chanspec, ucode interface */
extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
chanspec_t chanspec,
bool mute, struct txpwr_limits *txpwr);
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
uint *blocks);
extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
u16 val, int bands);
extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
extern u16 brcms_b_mhf_get(struct brcms_hardware *wlc_hw, u8 idx, int bands);
extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
u8 antsel_type);
extern int brcms_b_state_get(struct brcms_hardware *wlc_hw,
struct brcms_b_state *state);
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_write_template_ram(struct brcms_hardware *wlc_hw,
int offset, int len, void *buf);
extern void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf,
uint *len);
extern void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw,
u8 *ea);
extern bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw);
extern void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw,
bool shortslot);
extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
u8 stf_mode);
extern void brcms_b_wait_for_wake(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_set_addrmatch(struct brcms_hardware *wlc_hw,
int match_reg_offset,
const u8 *addr);
extern void brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw,
void *bcn, int len, bool both);
extern void brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
u32 *tsf_h_ptr);
extern void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin);
extern void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax);
extern void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL,
u16 LRL);
extern void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw);
/* API for BMAC driver (e.g. wlc_phy.c etc) */
extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
extern void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set,
mbool req_bit);
extern void brcms_b_hw_up(struct brcms_hardware *wlc_hw);
extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
extern void brcms_b_antsel_set(struct brcms_hardware *wlc_hw,
u32 antsel_avail);
#endif /* _BRCM_BOTTOM_MAC_H_ */

View File

@ -14,12 +14,12 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _WLC_CHANNEL_H_
#define _WLC_CHANNEL_H_
#ifndef _BRCM_CHANNEL_H_
#define _BRCM_CHANNEL_H_
#define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */
/* conversion for phy txpwr calculations that use .25 dB units */
#define BRCMS_TXPWR_DB_FACTOR 4
struct wlc_info;
/* maxpwr mapping to 5GHz band channels:
* maxpwr[0] - channels [34-48]
@ -47,43 +47,56 @@ struct wlc_info;
#define CHANNEL_POWER_IDX_5G(c) \
(((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4))))
#define WLC_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
#define WLC_MAXPWR_MIMO_TBL_SIZE 14 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
#define BRCMS_MAXPWR_TBL_SIZE 6
/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
#define BRCMS_MAXPWR_MIMO_TBL_SIZE 14
#define NBANDS(wlc) ((wlc)->pub->_nbands)
#define NBANDS_PUB(pub) ((pub)->_nbands)
#define NBANDS_HW(hw) ((hw)->_nbands)
#define IS_SINGLEBAND_5G(device) 0
/* locale channel and power info. */
typedef struct {
struct locale_info {
u32 valid_channels;
u8 radar_channels; /* List of radar sensitive channels */
u8 restricted_channels; /* List of channels used only if APs are detected */
s8 maxpwr[WLC_MAXPWR_TBL_SIZE]; /* Max tx pwr in qdBm for each sub-band */
/* List of radar sensitive channels */
u8 radar_channels;
/* List of channels used only if APs are detected */
u8 restricted_channels;
/* Max tx pwr in qdBm for each sub-band */
s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE];
s8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm
* per sub-band
*/
u8 flags;
} locale_info_t;
};
/* bits for locale_info flags */
#define WLC_PEAK_CONDUCTED 0x00 /* Peak for locals */
#define WLC_EIRP 0x01 /* Flag for EIRP */
#define WLC_DFS_TPC 0x02 /* Flag for DFS TPC */
#define WLC_NO_OFDM 0x04 /* Flag for No OFDM */
#define WLC_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */
#define WLC_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */
#define WLC_RADAR_TYPE_EU 0x20 /* Flag for EU */
#define WLC_DFS_FCC WLC_DFS_TPC /* Flag for DFS FCC */
#define WLC_DFS_EU (WLC_DFS_TPC | WLC_RADAR_TYPE_EU) /* Flag for DFS EU */
#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 */
#define ISDFS_EU(fl) (((fl) & WLC_DFS_EU) == WLC_DFS_EU)
#define ISDFS_EU(fl) (((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU)
/* locale per-channel tx power limits for MIMO frames
* maxpwr arrays are index by channel for 2.4 GHz limits, and
* by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
*/
typedef struct {
s8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 20 MHz power limits, qdBm units */
s8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */
struct locale_mimo_info {
/* tx 20 MHz power limits, qdBm units */
s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
/* tx 40 MHz power limits, qdBm units */
s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
u8 flags;
} locale_mimo_info_t;
};
extern const chanvec_t chanvec_all_2G;
extern const chanvec_t chanvec_all_5G;
@ -98,22 +111,21 @@ struct country_info {
const u8 locale_mimo_5G; /* 5G mimo info */
};
typedef struct country_info country_info_t;
extern struct brcms_cm_info *
brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
typedef struct wlc_cm_info wlc_cm_info_t;
extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc);
extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm);
extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm,
extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
uint bandunit);
extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec);
extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
chanspec_t chspec);
extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm,
extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
chanspec_t chanspec,
struct txpwr_limits *txpwr);
extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm,
extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
chanspec_t chanspec,
u8 local_constraint_qdbm);

View File

@ -14,23 +14,14 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _D11_H
#define _D11_H
#ifndef _BRCM_D11_H_
#define _BRCM_D11_H_
#include <sbconfig.h>
#include <linux/ieee80211.h>
#ifndef WL_RSSI_ANT_MAX
#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */
#elif WL_RSSI_ANT_MAX != 4
#error "WL_RSSI_ANT_MAX does not match"
#endif
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif
#include <defs.h>
#include "pub.h"
#include "dma.h"
#define BCN_TMPL_LEN 512 /* length of the BCN template area */
@ -56,10 +47,16 @@
#define TX_DATA_FIFO TX_AC_BE_FIFO
#define TX_CTL_FIFO TX_AC_VO_FIFO
typedef volatile struct {
#ifndef WL_RSSI_ANT_MAX
#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */
#elif WL_RSSI_ANT_MAX != 4
#error "WL_RSSI_ANT_MAX does not match"
#endif
struct intctrlregs {
u32 intstatus;
u32 intmask;
} intctrlregs_t;
};
/* PIO structure,
* support two PIO format: 2 bytes access and 4 bytes access
@ -67,55 +64,53 @@ typedef volatile struct {
* a pair of channels is defined for convenience
*/
/* 2byte-wide pio register set per channel(xmt or rcv) */
typedef volatile struct {
struct pio2regs {
u16 fifocontrol;
u16 fifodata;
u16 fifofree; /* only valid in xmt channel, not in rcv channel */
u16 PAD;
} pio2regs_t;
};
/* a pair of pio channels(tx and rx) */
typedef volatile struct {
struct pio2regp {
pio2regs_t tx;
pio2regs_t rx;
} pio2regp_t;
};
/* 4byte-wide pio register set per channel(xmt or rcv) */
typedef volatile struct {
struct pio4regs {
u32 fifocontrol;
u32 fifodata;
} pio4regs_t;
};
/* a pair of pio channels(tx and rx) */
typedef volatile struct {
struct pio4regp {
pio4regs_t tx;
pio4regs_t rx;
} pio4regp_t;
};
/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
* write: only low 16b-it half can be written
*/
typedef volatile union {
union pmqreg {
u32 pmqhostdata; /* read only! */
struct {
u16 pmqctrlstatus; /* read/write */
u16 PAD;
} w;
} pmqreg_t;
};
typedef volatile struct {
struct fifo64 {
dma64regs_t dmaxmt; /* dma tx */
pio4regs_t piotx; /* pio tx */
dma64regs_t dmarcv; /* dma rx */
pio4regs_t piorx; /* pio rx */
} fifo64_t;
};
/*
* Host Interface Registers
* - primed from hnd_cores/dot11mac/systemC/registers/ihr.h
* - but definitely not complete
*/
typedef volatile struct _d11regs {
struct d11regs {
/* Device Control ("semi-standard host registers") */
u32 PAD[3]; /* 0x0 - 0x8 */
u32 biststatus; /* 0xC */
@ -439,10 +434,7 @@ typedef volatile struct _d11regs {
/* SHM *//* 0x800 - 0xEFE */
u16 PAD[0x380]; /* 0x800 - 0xEFE */
/* SB configuration registers: 0xF00 */
sbconfig_t sbconfig; /* sb config regs occupy top 256 bytes */
} d11regs_t;
};
#define PIHR_BASE 0x0400 /* byte address of packed IHR region */
@ -629,12 +621,11 @@ typedef volatile struct _d11regs {
#define ANA_11N_013 5
/* 802.11a PLCP header def */
typedef struct ofdm_phy_hdr ofdm_phy_hdr_t;
struct ofdm_phy_hdr {
u8 rlpt[3]; /* rate, length, parity, tail */
u16 service;
u8 pad;
} __attribute__((packed));
} __packed;
#define D11A_PHY_HDR_GRATE(phdr) ((phdr)->rlpt[0] & 0x0f)
#define D11A_PHY_HDR_GRES(phdr) (((phdr)->rlpt[0] >> 4) & 0x01)
@ -664,13 +655,12 @@ struct ofdm_phy_hdr {
#define D11A_PHY_PREHDR_TIME (D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
/* 802.11b PLCP header def */
typedef struct cck_phy_hdr cck_phy_hdr_t;
struct cck_phy_hdr {
u8 signal;
u8 service;
u16 length;
u16 crc;
} __attribute__((packed));
} __packed;
#define D11B_PHY_HDR_LEN 6
@ -691,17 +681,17 @@ struct cck_phy_hdr {
#define MIMO_PLCP_40MHZ 0x80 /* 40 Hz frame */
#define MIMO_PLCP_AMPDU 0x08 /* ampdu */
#define WLC_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
#define WLC_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
#define WLC_SET_MIMO_PLCP_LEN(plcp, len) \
#define BRCMS_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
#define BRCMS_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
#define BRCMS_SET_MIMO_PLCP_LEN(plcp, len) \
do { \
plcp[1] = len & 0xff; \
plcp[2] = ((len >> 8) & 0xff); \
} while (0);
#define WLC_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
#define WLC_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
#define WLC_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
#define BRCMS_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
#define BRCMS_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
#define BRCMS_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
/* The dot11a PLCP header is 5 bytes. To simplify the software (so that we
* don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header has
@ -710,7 +700,6 @@ struct cck_phy_hdr {
#define D11_PHY_HDR_LEN 6
/* TX DMA buffer header */
typedef struct d11txh d11txh_t;
struct d11txh {
u16 MacTxControlLow; /* 0x0 */
u16 MacTxControlHigh; /* 0x1 */
@ -746,7 +735,7 @@ struct d11txh {
u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */
struct ieee80211_rts rts_frame; /* 0x2f - 0x36 */
u16 PAD; /* 0x37 */
} __attribute__((packed));
} __packed;
#define D11_TXH_LEN 112 /* bytes */
@ -854,7 +843,6 @@ struct d11txh {
#define ABI_MAS_MRT_ANT_PTN_MASK 0x000f
/* tx status packet */
typedef struct tx_status tx_status_t;
struct tx_status {
u16 framelen;
u16 PAD;
@ -864,7 +852,7 @@ struct tx_status {
u16 sequence;
u16 phyerr;
u16 ackphyrxsh;
} __attribute__((packed));
} __packed;
#define TXSTATUS_LEN 16
@ -1160,25 +1148,25 @@ struct tx_status {
#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
/* CW RSSI for LCNPHY */
#define M_LCN_RSSI_0 0x1332
#define M_LCN_RSSI_1 0x1338
#define M_LCN_RSSI_2 0x133e
#define M_LCN_RSSI_3 0x1344
#define M_LCN_RSSI_0 0x1332
#define M_LCN_RSSI_1 0x1338
#define M_LCN_RSSI_2 0x133e
#define M_LCN_RSSI_3 0x1344
/* SNR for LCNPHY */
#define M_LCN_SNR_A_0 0x1334
#define M_LCN_SNR_B_0 0x1336
#define M_LCN_SNR_A_0 0x1334
#define M_LCN_SNR_B_0 0x1336
#define M_LCN_SNR_A_1 0x133a
#define M_LCN_SNR_B_1 0x133c
#define M_LCN_SNR_A_1 0x133a
#define M_LCN_SNR_B_1 0x133c
#define M_LCN_SNR_A_2 0x1340
#define M_LCN_SNR_B_2 0x1342
#define M_LCN_SNR_A_2 0x1340
#define M_LCN_SNR_B_2 0x1342
#define M_LCN_SNR_A_3 0x1346
#define M_LCN_SNR_B_3 0x1348
#define M_LCN_SNR_A_3 0x1346
#define M_LCN_SNR_B_3 0x1348
#define M_LCN_LAST_RESET (81*2)
#define M_LCN_LAST_RESET (81*2)
#define M_LCN_LAST_LOC (63*2)
#define M_LCNPHY_RESET_STATUS (4902)
#define M_LCNPHY_DSC_TIME (0x98d*2)
@ -1247,7 +1235,6 @@ struct tx_status {
#define MIMO_ANTSEL_WAIT 50 /* 50us wait */
#define MIMO_ANTSEL_OVERRIDE 0x8000 /* flag */
typedef struct shm_acparams shm_acparams_t;
struct shm_acparams {
u16 txop;
u16 cwmin;
@ -1258,7 +1245,7 @@ struct shm_acparams {
u16 reggap;
u16 status;
u16 rsvd[8];
} __attribute__((packed));
} __packed;
#define M_EDCF_QLEN (16 * 2)
#define WME_STATUS_NEWAC (1 << 8)
@ -1292,7 +1279,7 @@ struct shm_acparams {
/* Flags in M_HOST_FLAGS4 */
#define MHF4_BPHY_TXCORE0 0x0080 /* force bphy Tx on core 0 (board level WAR) */
#define MHF4_EXTPA_ENABLE 0x4000 /* for 4313A0 FEM boards */
#define MHF4_EXTPA_ENABLE 0x4000 /* for 4313A0 FEM boards */
/* Flags in M_HOST_FLAGS5 */
#define MHF5_4313_GPIOCTRL 0x0001
@ -1306,7 +1293,6 @@ struct shm_acparams {
#define PHY_NOISE_MASK 0x00ff
/* Receive Frame Data Header for 802.11b DCF-only frames */
typedef struct d11rxhdr d11rxhdr_t;
struct d11rxhdr {
u16 RxFrameSize; /* Actual byte length of the frame data received */
u16 PAD;
@ -1320,21 +1306,20 @@ struct d11rxhdr {
u16 RxStatus2; /* extended MAC Rx status */
u16 RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */
u16 RxChan; /* gain code, channel radio code, and phy type */
} __attribute__((packed));
} __packed;
#define RXHDR_LEN 24 /* sizeof d11rxhdr_t */
#define RXHDR_LEN 24 /* sizeof struct d11rxhdr */
#define FRAMELEN(h) ((h)->RxFrameSize)
typedef struct wlc_d11rxhdr wlc_d11rxhdr_t;
struct wlc_d11rxhdr {
d11rxhdr_t rxhdr;
struct brcms_d11rxhdr {
struct d11rxhdr rxhdr;
u32 tsf_l; /* TSF_L reading */
s8 rssi; /* computed instanteneous rssi in BMAC */
s8 rxpwr0; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */
s8 rxpwr1; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */
s8 do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */
s8 rxpwr[WL_RSSI_ANT_MAX]; /* rssi for supported antennas */
} __attribute__((packed));
} __packed;
/* PhyRxStatus_0: */
#define PRXS0_FT_MASK 0x0003 /* NPHY only: CCK, OFDM, preN, N */
@ -1473,7 +1458,7 @@ struct wlc_d11rxhdr {
#define DBGST_ASLEEP 4 /* asleep (PS mode) */
/* Scratch Reg defs */
typedef enum {
enum _ePsmScratchPadRegDefinitions {
S_RSV0 = 0,
S_RSV1,
S_RSV2,
@ -1551,7 +1536,7 @@ typedef enum {
S_MFGTEST_TMP0, /* Temp register used for RX test calculations 0x3D */
S_RXESN, /* Received end sequence number for A-MPDU BA 0x3E */
S_STREG6, /* 0x3F */
} ePsmScratchPadRegDefinitions;
};
#define S_BEACON_INDX S_OLD_BREM
#define S_PRS_INDX S_OLD_CWWIN
@ -1563,7 +1548,7 @@ typedef enum {
#define SLOW_CTRL_FD (1 << 8)
/* ucode mac statistic counters in shared memory */
typedef struct macstat {
struct macstat {
u16 txallfrm; /* 0x80 */
u16 txrtsfrm; /* 0x82 */
u16 txctsfrm; /* 0x84 */
@ -1621,7 +1606,7 @@ typedef struct macstat {
u16 phywatchdog; /* 0xfa # of phy watchdog events */
u16 PAD;
u16 bphy_badplcp; /* bphy bad plcp */
} macstat_t;
};
/* dot11 core-specific control flags */
#define SICF_PCLKE 0x0004 /* PHY clock enable */
@ -1688,7 +1673,7 @@ typedef struct macstat {
#define BPHY_PEAK_ENERGY_HI 0x34
#define BPHY_SYNC_CTL 0x35
#define BPHY_TX_PWR_CTRL 0x36
#define BPHY_TX_EST_PWR 0x37
#define BPHY_TX_EST_PWR 0x37
#define BPHY_STEP 0x38
#define BPHY_WARMUP 0x39
#define BPHY_LMS_CFF_READ 0x3a
@ -1770,4 +1755,21 @@ typedef struct macstat {
#define SHM_BYT_CNT 0x2 /* IHR location */
#define MAX_BYT_CNT 0x600 /* Maximum frame len */
#endif /* _D11_H */
struct d11cnt {
u32 txfrag;
u32 txmulti;
u32 txfail;
u32 txretry;
u32 txretrie;
u32 rxdup;
u32 txrts;
u32 txnocts;
u32 txnoack;
u32 rxfrag;
u32 rxmulti;
u32 rxcrc;
u32 txfrmsnt;
u32 rxundec;
};
#endif /* _BRCM_D11_H_ */

View File

@ -14,13 +14,37 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _hnddma_h_
#define _hnddma_h_
#ifndef _BRCM_DMA_H_
#define _BRCM_DMA_H_
#ifndef _hnddma_pub_
#define _hnddma_pub_
struct hnddma_pub;
#endif /* _hnddma_pub_ */
#include "types.h" /* forward structure declarations */
/* 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; /* descriptor ring base address low 32-bits (8K aligned) */
u32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
u32 status0; /* current descriptor, xmt state */
u32 status1; /* active descriptor, xmt error */
};
/* map/unmap direction */
#define DMA_TX 1 /* TX direction for DMA */
@ -28,64 +52,64 @@ struct hnddma_pub;
#define BUS_SWAP32(v) (v)
/* range param for dma_getnexttxp() and dma_txreclaim */
typedef enum txd_range {
HNDDMA_RANGE_ALL = 1,
HNDDMA_RANGE_TRANSMITTED,
HNDDMA_RANGE_TRANSFERED
} txd_range_t;
enum txd_range {
DMA_RANGE_ALL = 1,
DMA_RANGE_TRANSMITTED,
DMA_RANGE_TRANSFERED
};
/* dma function type */
typedef void (*di_detach_t) (struct hnddma_pub *dmah);
typedef bool(*di_txreset_t) (struct hnddma_pub *dmah);
typedef bool(*di_rxreset_t) (struct hnddma_pub *dmah);
typedef bool(*di_rxidle_t) (struct hnddma_pub *dmah);
typedef void (*di_txinit_t) (struct hnddma_pub *dmah);
typedef bool(*di_txenabled_t) (struct hnddma_pub *dmah);
typedef void (*di_rxinit_t) (struct hnddma_pub *dmah);
typedef void (*di_txsuspend_t) (struct hnddma_pub *dmah);
typedef void (*di_txresume_t) (struct hnddma_pub *dmah);
typedef bool(*di_txsuspended_t) (struct hnddma_pub *dmah);
typedef bool(*di_txsuspendedidle_t) (struct hnddma_pub *dmah);
typedef int (*di_txfast_t) (struct hnddma_pub *dmah, struct sk_buff *p,
typedef void (*di_detach_t) (struct dma_pub *dmah);
typedef bool(*di_txreset_t) (struct dma_pub *dmah);
typedef bool(*di_rxreset_t) (struct dma_pub *dmah);
typedef bool(*di_rxidle_t) (struct dma_pub *dmah);
typedef void (*di_txinit_t) (struct dma_pub *dmah);
typedef bool(*di_txenabled_t) (struct dma_pub *dmah);
typedef void (*di_rxinit_t) (struct dma_pub *dmah);
typedef void (*di_txsuspend_t) (struct dma_pub *dmah);
typedef void (*di_txresume_t) (struct dma_pub *dmah);
typedef bool(*di_txsuspended_t) (struct dma_pub *dmah);
typedef bool(*di_txsuspendedidle_t) (struct dma_pub *dmah);
typedef int (*di_txfast_t) (struct dma_pub *dmah, struct sk_buff *p,
bool commit);
typedef int (*di_txunframed_t) (struct hnddma_pub *dmah, void *p, uint len,
typedef int (*di_txunframed_t) (struct dma_pub *dmah, void *p, uint len,
bool commit);
typedef void *(*di_getpos_t) (struct hnddma_pub *di, bool direction);
typedef void (*di_fifoloopbackenable_t) (struct hnddma_pub *dmah);
typedef bool(*di_txstopped_t) (struct hnddma_pub *dmah);
typedef bool(*di_rxstopped_t) (struct hnddma_pub *dmah);
typedef bool(*di_rxenable_t) (struct hnddma_pub *dmah);
typedef bool(*di_rxenabled_t) (struct hnddma_pub *dmah);
typedef void *(*di_rx_t) (struct hnddma_pub *dmah);
typedef bool(*di_rxfill_t) (struct hnddma_pub *dmah);
typedef void (*di_txreclaim_t) (struct hnddma_pub *dmah, txd_range_t range);
typedef void (*di_rxreclaim_t) (struct hnddma_pub *dmah);
typedef unsigned long (*di_getvar_t) (struct hnddma_pub *dmah,
typedef void *(*di_getpos_t) (struct dma_pub *di, bool direction);
typedef void (*di_fifoloopbackenable_t) (struct dma_pub *dmah);
typedef bool(*di_txstopped_t) (struct dma_pub *dmah);
typedef bool(*di_rxstopped_t) (struct dma_pub *dmah);
typedef bool(*di_rxenable_t) (struct dma_pub *dmah);
typedef bool(*di_rxenabled_t) (struct dma_pub *dmah);
typedef void *(*di_rx_t) (struct dma_pub *dmah);
typedef bool(*di_rxfill_t) (struct dma_pub *dmah);
typedef void (*di_txreclaim_t) (struct dma_pub *dmah, enum txd_range range);
typedef void (*di_rxreclaim_t) (struct dma_pub *dmah);
typedef unsigned long (*di_getvar_t) (struct dma_pub *dmah,
const char *name);
typedef void *(*di_getnexttxp_t) (struct hnddma_pub *dmah, txd_range_t range);
typedef void *(*di_getnextrxp_t) (struct hnddma_pub *dmah, bool forceall);
typedef void *(*di_peeknexttxp_t) (struct hnddma_pub *dmah);
typedef void *(*di_peeknextrxp_t) (struct hnddma_pub *dmah);
typedef void (*di_rxparam_get_t) (struct hnddma_pub *dmah, u16 *rxoffset,
typedef void *(*di_getnexttxp_t) (struct dma_pub *dmah, enum txd_range range);
typedef void *(*di_getnextrxp_t) (struct dma_pub *dmah, bool forceall);
typedef void *(*di_peeknexttxp_t) (struct dma_pub *dmah);
typedef void *(*di_peeknextrxp_t) (struct dma_pub *dmah);
typedef void (*di_rxparam_get_t) (struct dma_pub *dmah, u16 *rxoffset,
u16 *rxbufsize);
typedef void (*di_txblock_t) (struct hnddma_pub *dmah);
typedef void (*di_txunblock_t) (struct hnddma_pub *dmah);
typedef uint(*di_txactive_t) (struct hnddma_pub *dmah);
typedef void (*di_txrotate_t) (struct hnddma_pub *dmah);
typedef void (*di_counterreset_t) (struct hnddma_pub *dmah);
typedef uint(*di_ctrlflags_t) (struct hnddma_pub *dmah, uint mask, uint flags);
typedef char *(*di_dump_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
typedef void (*di_txblock_t) (struct dma_pub *dmah);
typedef void (*di_txunblock_t) (struct dma_pub *dmah);
typedef uint(*di_txactive_t) (struct dma_pub *dmah);
typedef void (*di_txrotate_t) (struct dma_pub *dmah);
typedef void (*di_counterreset_t) (struct dma_pub *dmah);
typedef uint(*di_ctrlflags_t) (struct dma_pub *dmah, uint mask, uint flags);
typedef char *(*di_dump_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
bool dumpring);
typedef char *(*di_dumptx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
typedef char *(*di_dumptx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
bool dumpring);
typedef char *(*di_dumprx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
typedef char *(*di_dumprx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
bool dumpring);
typedef uint(*di_rxactive_t) (struct hnddma_pub *dmah);
typedef uint(*di_txpending_t) (struct hnddma_pub *dmah);
typedef uint(*di_txcommitted_t) (struct hnddma_pub *dmah);
typedef uint(*di_rxactive_t) (struct dma_pub *dmah);
typedef uint(*di_txpending_t) (struct dma_pub *dmah);
typedef uint(*di_txcommitted_t) (struct dma_pub *dmah);
/* dma opsvec */
typedef struct di_fcn_s {
struct di_fcn_s {
di_detach_t detach;
di_txinit_t txinit;
di_txreset_t txreset;
@ -130,14 +154,14 @@ typedef struct di_fcn_s {
di_txpending_t txpending;
di_txcommitted_t txcommitted;
uint endnum;
} di_fcn_t;
};
/*
* Exported data structure (read-only)
*/
/* export structure */
struct hnddma_pub {
const di_fcn_t *di_fn; /* DMA function pointers */
struct dma_pub {
const struct di_fcn_s *di_fn; /* DMA function pointers */
uint txavail; /* # free tx descriptors */
uint dmactrlflags; /* dma control flags */
@ -148,12 +172,12 @@ struct hnddma_pub {
uint txnobuf; /* tx out of dma descriptors */
};
extern struct hnddma_pub *dma_attach(char *name, si_t *sih,
extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
void *dmaregstx, void *dmaregsrx, uint ntxd,
uint nrxd, uint rxbufsize, int rxextheadroom,
uint nrxpost, uint rxoffset, uint *msg_level);
extern const di_fcn_t dma64proc;
extern const struct di_fcn_s dma64proc;
#define dma_detach(di) (dma64proc.detach(di))
#define dma_txreset(di) (dma64proc.txreset(di))
@ -201,8 +225,8 @@ extern const di_fcn_t dma64proc;
* SB attach provides ability to probe backplane and dma core capabilities
* This info is needed by DMA_ALLOC_CONSISTENT in dma attach
*/
extern uint dma_addrwidth(si_t *sih, void *dmaregs);
void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
extern uint dma_addrwidth(struct si_pub *sih, void *dmaregs);
void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
(void *pkt, void *arg_a), void *arg_a);
/*
@ -223,4 +247,4 @@ static inline void dma_spin_for_len(uint len, struct sk_buff *head)
#endif /* defined(__mips__) */
}
#endif /* _hnddma_h_ */
#endif /* _BRCM_DMA_H_ */

View File

@ -14,8 +14,15 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _wl_mac80211_h_
#define _wl_mac80211_h_
#ifndef _BRCM_MAC80211_IF_H_
#define _BRCM_MAC80211_IF_H_
#include <linux/timer.h>
#include <linux/interrupt.h>
/* softmac ioctl definitions */
#define BRCMS_SET_SHORTSLOT_OVERRIDE 146
#include <linux/interrupt.h>
@ -23,35 +30,35 @@
* sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be
* submitted to workqueue instead of being on kernel timer
*/
struct wl_timer {
struct brcms_timer {
struct timer_list timer;
struct wl_info *wl;
struct brcms_info *wl;
void (*fn) (void *);
void *arg; /* argument to fn */
uint ms;
bool periodic;
bool set;
struct wl_timer *next;
struct brcms_timer *next;
#ifdef BCMDBG
char *name; /* Description of the timer */
#endif
};
struct wl_if {
struct brcms_if {
uint subunit; /* WDS/BSS unit */
struct pci_dev *pci_dev;
};
#define WL_MAX_FW 4
struct wl_firmware {
#define MAX_FW_IMAGES 4
struct brcms_firmware {
u32 fw_cnt;
const struct firmware *fw_bin[WL_MAX_FW];
const struct firmware *fw_hdr[WL_MAX_FW];
u32 hdr_num_entries[WL_MAX_FW];
const struct firmware *fw_bin[MAX_FW_IMAGES];
const struct firmware *fw_hdr[MAX_FW_IMAGES];
u32 hdr_num_entries[MAX_FW_IMAGES];
};
struct wl_info {
struct wlc_pub *pub; /* pointer to public wlc state */
struct brcms_info {
struct brcms_pub *pub; /* pointer to public wlc state */
void *wlc; /* pointer to private common os-independent data */
u32 magic;
@ -59,29 +66,45 @@ struct wl_info {
spinlock_t lock; /* per-device perimeter lock */
spinlock_t isr_lock; /* per-device ISR synchronization lock */
/* bus type and regsva for unmap in brcms_free() */
uint bcm_bustype; /* bus type */
bool piomode; /* set from insmod argument */
void *regsva; /* opaque chip registers virtual address */
/* timer related fields */
atomic_t callbacks; /* # outstanding callback functions */
struct wl_timer *timers; /* timer cleanup queue */
struct brcms_timer *timers; /* timer cleanup queue */
struct tasklet_struct tasklet; /* dpc tasklet */
bool resched; /* dpc needs to be and is rescheduled */
#ifdef LINUXSTA_PS
u32 pci_psstate[16]; /* pci ps-state save/restore */
#endif
struct wl_firmware fw;
struct brcms_firmware fw;
struct wiphy *wiphy;
};
#define WL_LOCK(wl) spin_lock_bh(&(wl)->lock)
#define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock)
/* 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 wl_alloc_dma_resources(struct brcms_info *wl, uint dmaddrwidth);
extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
/* locking from inside wl_isr */
#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0)
#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0)
/* 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);
/* locking under WL_LOCK() to synchronize with wl_isr */
#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags)
#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags)
#endif /* _wl_mac80211_h_ */
#endif /* _BRCM_MAC80211_IF_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
/*
* 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)
#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */
/* 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 */
/* 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 */
extern void *pcicore_init(struct si_pub *sih, void *pdev, void *regs);
extern void pcicore_deinit(void *pch);
extern void pcicore_attach(void *pch, char *pvars, int state);
extern void pcicore_hwup(void *pch);
extern void pcicore_up(void *pch, int state);
extern void pcicore_sleep(void *pch);
extern void pcicore_down(void *pch, int state);
extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id,
unsigned char *buf, u32 *buflen);
extern void pcicore_fixcfg(void *pch, void *regs);
extern void pcicore_pci_setup(void *pch, void *regs);
#endif /* _BRCM_NICPCI_H_ */

View File

@ -1,215 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/slab.h>
#include <linux/string.h>
#include <bcmdefs.h>
#include <bcmutils.h>
#include <bcmnvram.h>
#include <sbchipc.h>
#include <bcmdevs.h>
#include <hndsoc.h>
#define NVR_MSG(x)
typedef struct _vars {
struct _vars *next;
int bufsz; /* allocated size */
int size; /* actual vars size */
char *vars;
} vars_t;
#define VARS_T_OH sizeof(vars_t)
static vars_t *vars;
#define NVRAM_FILE 1
static char *findvar(char *vars, char *lim, const char *name);
int nvram_init(void)
{
/* Make sure we read nvram in flash just once before freeing the memory */
if (vars != NULL) {
NVR_MSG(("nvram_init: called again without calling nvram_exit()\n"));
return 0;
}
return 0;
}
int nvram_append(char *varlst, uint varsz)
{
uint bufsz = VARS_T_OH;
vars_t *new;
new = kmalloc(bufsz, GFP_ATOMIC);
if (new == NULL)
return -ENOMEM;
new->vars = varlst;
new->bufsz = bufsz;
new->size = varsz;
new->next = vars;
vars = new;
return 0;
}
void nvram_exit(void)
{
vars_t *this, *next;
this = vars;
if (this)
kfree(this->vars);
while (this) {
next = this->next;
kfree(this);
this = next;
}
vars = NULL;
}
static char *findvar(char *vars, char *lim, const char *name)
{
char *s;
int len;
len = strlen(name);
for (s = vars; (s < lim) && *s;) {
if ((memcmp(s, name, len) == 0) && (s[len] == '='))
return &s[len + 1];
while (*s++)
;
}
return NULL;
}
/*
* Search the name=value vars for a specific one and return its value.
* Returns NULL if not found.
*/
char *getvar(char *vars, const char *name)
{
char *s;
int len;
if (!name)
return NULL;
len = strlen(name);
if (len == 0)
return NULL;
/* first look in vars[] */
for (s = vars; s && *s;) {
if ((memcmp(s, name, len) == 0) && (s[len] == '='))
return &s[len + 1];
while (*s++)
;
}
/* then query nvram */
return nvram_get(name);
}
/*
* Search the vars for a specific one and return its value as
* an integer. Returns 0 if not found.
*/
int getintvar(char *vars, const char *name)
{
char *val;
val = getvar(vars, name);
if (val == NULL)
return 0;
return simple_strtoul(val, NULL, 0);
}
char *nvram_get(const char *name)
{
char *v = NULL;
vars_t *cur;
for (cur = vars; cur; cur = cur->next) {
v = findvar(cur->vars, cur->vars + cur->size, name);
if (v)
break;
}
return v;
}
int nvram_set(const char *name, const char *value)
{
return 0;
}
int nvram_unset(const char *name)
{
return 0;
}
int nvram_reset(void)
{
return 0;
}
int nvram_commit(void)
{
return 0;
}
int nvram_getall(char *buf, int count)
{
int len, resid = count;
vars_t *this;
this = vars;
while (this) {
char *from, *lim, *to;
int acc;
from = this->vars;
lim = (char *)(this->vars + this->size);
to = buf;
acc = 0;
while ((from < lim) && (*from)) {
len = strlen(from) + 1;
if (resid < (acc + len))
return -EOVERFLOW;
memcpy(to, from, len);
acc += len;
from += len;
to += len;
}
resid -= acc;
buf += acc;
this = this->next;
}
if (resid < 1)
return -EOVERFLOW;
*buf = '\0';
return 0;
}

View File

@ -0,0 +1,544 @@
/*
* 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 <brcm_hw_ids.h>
#include <chipcommon.h>
#include "aiutils.h"
#include "otp.h"
#define OTPS_GUP_MASK 0x00000f00
#define OTPS_GUP_SHIFT 8
#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */
#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */
#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */
#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */
/* 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 */
/* OTP common function type */
typedef int (*otp_status_t) (void *oh);
typedef int (*otp_size_t) (void *oh);
typedef void *(*otp_init_t) (struct si_pub *sih);
typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
typedef int (*otp_read_region_t) (struct si_pub *sih, int region, u16 *data,
uint *wlen);
typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
/* OTP function struct */
struct otp_fn_s {
otp_size_t size;
otp_read_bit_t read_bit;
otp_init_t init;
otp_read_region_t read_region;
otp_nvread_t nvread;
otp_status_t status;
};
struct otpinfo {
uint ccrev; /* chipc revision */
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 */
};
static struct otpinfo otpinfo;
/*
* IPX OTP Code
*
* Exported functions:
* ipxotp_status()
* ipxotp_size()
* ipxotp_init()
* ipxotp_read_bit()
* ipxotp_read_region()
* ipxotp_nvread()
*
*/
#define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
/* 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 int ipxotp_status(void *oh)
{
struct otpinfo *oi = (struct otpinfo *) oh;
return (int)(oi->status);
}
/* Return size in bytes */
static int ipxotp_size(void *oh)
{
struct otpinfo *oi = (struct otpinfo *) oh;
return (int)oi->wsize * 2;
}
static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
{
struct otpinfo *oi;
oi = (struct otpinfo *) oh;
return R_REG(&cc->sromotp[wn]);
}
static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
{
struct otpinfo *oi = (struct otpinfo *) oh;
uint k, row, col;
u32 otpp, st;
row = off / oi->cols;
col = off % oi->cols;
otpp = OTPP_START_BUSY |
((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
((col << OTPP_COL_SHIFT) & OTPP_COL_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 0xffff;
}
if (st & OTPP_READERR) {
return 0xffff;
}
st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
return (int)st;
}
/* 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, chipcregs_t *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 void *ipxotp_init(struct si_pub *sih)
{
uint idx;
chipcregs_t *cc;
struct otpinfo *oi;
/* Make sure we're running IPX OTP */
if (!OTPTYPE_IPX(sih->ccrev))
return NULL;
/* Make sure OTP is not disabled */
if (ai_is_otp_disabled(sih))
return NULL;
/* OTP is always powered */
oi = &otpinfo;
/* Check for otp size */
switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
case 0:
/* Nothing there */
return NULL;
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 NULL;
}
/* Retrieve OTP region info */
idx = ai_coreidx(sih);
cc = ai_setcoreidx(sih, SI_CC_IDX);
_ipxotp_init(oi, cc);
ai_setcoreidx(sih, idx);
return (void *)oi;
}
static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
{
struct otpinfo *oi = (struct otpinfo *) oh;
uint idx;
chipcregs_t *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(oh, cc, base + i);
ai_setcoreidx(oi->sih, idx);
*wlen = sz;
return 0;
}
static int ipxotp_nvread(void *oh, char *data, uint *len)
{
return -ENOTSUPP;
}
static struct otp_fn_s ipxotp_fn = {
(otp_size_t) ipxotp_size,
(otp_read_bit_t) ipxotp_read_bit,
(otp_init_t) ipxotp_init,
(otp_read_region_t) ipxotp_read_region,
(otp_nvread_t) ipxotp_nvread,
(otp_status_t) ipxotp_status
};
/*
* otp_status()
* otp_size()
* otp_read_bit()
* otp_init()
* otp_read_region()
* otp_nvread()
*/
int otp_status(void *oh)
{
struct otpinfo *oi = (struct otpinfo *) oh;
return oi->fn->status(oh);
}
int otp_size(void *oh)
{
struct otpinfo *oi = (struct otpinfo *) oh;
return oi->fn->size(oh);
}
u16 otp_read_bit(void *oh, uint offset)
{
struct otpinfo *oi = (struct otpinfo *) oh;
uint idx = ai_coreidx(oi->sih);
chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
ai_setcoreidx(oi->sih, idx);
return readBit;
}
void *otp_init(struct si_pub *sih)
{
struct otpinfo *oi;
void *ret = NULL;
oi = &otpinfo;
memset(oi, 0, sizeof(struct otpinfo));
oi->ccrev = sih->ccrev;
if (OTPTYPE_IPX(oi->ccrev))
oi->fn = &ipxotp_fn;
if (oi->fn == NULL) {
return NULL;
}
oi->sih = sih;
ret = (oi->fn->init) (sih);
return ret;
}
int
otp_read_region(struct si_pub *sih, int region, u16 *data,
uint *wlen) {
void *oh;
int err = 0;
if (ai_is_otp_disabled(sih)) {
err = -EPERM;
goto out;
}
oh = otp_init(sih);
if (oh == NULL) {
err = -EBADE;
goto out;
}
err = (((struct otpinfo *) oh)->fn->read_region)
(oh, region, data, wlen);
out:
return err;
}
int otp_nvread(void *oh, char *data, uint *len)
{
struct otpinfo *oi = (struct otpinfo *) oh;
return oi->fn->nvread(oh, data, len);
}

View File

@ -14,8 +14,10 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _bcmotp_h_
#define _bcmotp_h_
#ifndef _BRCM_OTP_H_
#define _BRCM_OTP_H_
#include "types.h"
/* OTP regions */
#define OTP_HW_RGN 1
@ -37,8 +39,9 @@
extern int otp_status(void *oh);
extern int otp_size(void *oh);
extern u16 otp_read_bit(void *oh, uint offset);
extern void *otp_init(si_t *sih);
extern int otp_read_region(si_t *sih, int region, u16 *data, uint *wlen);
extern void *otp_init(struct si_pub *sih);
extern int otp_read_region(struct si_pub *sih, int region, u16 *data,
uint *wlen);
extern int otp_nvread(void *oh, char *data, uint *len);
#endif /* _bcmotp_h_ */
#endif /* _BRCM_OTP_H_ */

View File

@ -0,0 +1,294 @@
/*
* 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 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;
chanspec_t chanspec; /* txpwr report for this channel */
chanspec_t 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 */
u8 tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */
u8 user_limit[WL_TX_POWER_RATES]; /* User limit */
u8 reg_limit[WL_TX_POWER_RATES]; /* Regulatory power limit */
u8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */
u8 target[WL_TX_POWER_RATES]; /* Latest target power */
};
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 chanvec {
u8 vec[MAXCHANNEL / NBBY];
};
struct shared_phy_params {
struct si_pub *sih;
void *physhim;
uint unit;
uint corerev;
uint bustype;
uint buscorerev;
char *vars;
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, void *regs,
int bandtype, char *vars, 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, chanspec_t 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,
chanspec_t chanspec);
extern chanspec_t wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
chanspec_t 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 void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx);
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,
chanvec_t *channels);
extern chanspec_t 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 *,
chanspec_t 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,
chanspec_t 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, mbool id, bool val);
extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, mbool 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_ */

View File

@ -14,15 +14,14 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _wlc_phy_int_h_
#define _wlc_phy_int_h_
#ifndef _BRCM_PHY_INT_H_
#define _BRCM_PHY_INT_H_
#include <linux/kernel.h>
#include <bcmdefs.h>
#include <bcmutils.h>
#include <types.h>
#include <brcmu_utils.h>
#include <brcmu_wifi.h>
#include <bcmsrom_fmt.h>
#include <wlc_phy_hal.h>
#define PHY_VERSION { 1, 82, 8, 0 }
#define PHYHAL_ERROR 0x0001
#define PHYHAL_TRACE 0x0002
@ -42,23 +41,29 @@ extern u32 phyhal_msg_level;
#define LCNXN_BASEREV 16
struct wlc_hw_info;
typedef struct phy_info phy_info_t;
typedef void (*initfn_t) (phy_info_t *);
typedef void (*chansetfn_t) (phy_info_t *, chanspec_t);
typedef int (*longtrnfn_t) (phy_info_t *, int);
typedef void (*txiqccgetfn_t) (phy_info_t *, u16 *, u16 *);
typedef void (*txiqccsetfn_t) (phy_info_t *, u16, u16);
typedef u16(*txloccgetfn_t) (phy_info_t *);
typedef void (*radioloftgetfn_t) (phy_info_t *, u8 *, u8 *, u8 *,
struct brcms_phy_srom_fem {
u8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */
u8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
u8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */
u8 triso; /* TR switch isolation */
u8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */
};
typedef void (*initfn_t) (struct brcms_phy *);
typedef void (*chansetfn_t) (struct brcms_phy *, chanspec_t);
typedef int (*longtrnfn_t) (struct brcms_phy *, int);
typedef void (*txiqccgetfn_t) (struct brcms_phy *, u16 *, u16 *);
typedef void (*txiqccsetfn_t) (struct brcms_phy *, u16, u16);
typedef u16(*txloccgetfn_t) (struct brcms_phy *);
typedef void (*radioloftgetfn_t) (struct brcms_phy *, u8 *, u8 *, u8 *,
u8 *);
typedef s32(*rxsigpwrfn_t) (phy_info_t *, s32);
typedef void (*detachfn_t) (phy_info_t *);
typedef s32(*rxsigpwrfn_t) (struct brcms_phy *, s32);
typedef void (*detachfn_t) (struct brcms_phy *);
#undef ISNPHY
#undef ISLCNPHY
#define ISNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
#define ISPHY_11N_CAP(pi) (ISNPHY(pi) || ISLCNPHY(pi))
@ -215,7 +220,7 @@ enum {
MPHASE_CAL_STATE_IDLETSSI
};
typedef enum {
enum phy_cal_mode {
CAL_FULL,
CAL_RECAL,
CAL_CURRECAL,
@ -223,7 +228,7 @@ typedef enum {
CAL_GCTRL,
CAL_SOFT,
CAL_DIGLO
} phy_cal_mode_t;
};
#define RDR_NTIERS 1
#define RDR_TIER_SIZE 64
@ -248,7 +253,7 @@ typedef enum {
#define PHY_CHAIN_TX_DISABLE_TEMP 115
#define PHY_HYSTERESIS_DELTATEMP 5
#define PHY_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8))
#define PHY_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8))
#define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \
mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \
@ -285,21 +290,21 @@ typedef enum {
#define PHY_LTRN_LIST_LEN 64
extern u16 ltrn_list[PHY_LTRN_LIST_LEN];
typedef struct _phy_table_info {
struct phy_table_info {
uint table;
int q;
uint max;
} phy_table_info_t;
};
typedef struct phytbl_info {
struct phytbl_info {
const void *tbl_ptr;
u32 tbl_len;
u32 tbl_id;
u32 tbl_offset;
u32 tbl_width;
} phytbl_info_t;
};
typedef struct {
struct interference_info {
u8 curr_home_channel;
u16 crsminpwrthld_40_stored;
u16 crsminpwrthld_20L_stored;
@ -369,10 +374,9 @@ typedef struct {
u16 radio_2057_core2_rssi_wb2_gc_stored;
u16 radio_2057_core1_rssi_nb_gc_stored;
u16 radio_2057_core2_rssi_nb_gc_stored;
};
} interference_info_t;
typedef struct {
struct aci_save_gphy {
u16 rc_cal_ovr;
u16 phycrsth1;
u16 phycrsth2;
@ -406,21 +410,21 @@ typedef struct {
u16 div_srch_gn_back;
u16 ant_dwell;
u16 ant_wr_settle;
} aci_save_gphy_t;
};
typedef struct _lo_complex_t {
struct lo_complex_abgphy_info {
s8 i;
s8 q;
} lo_complex_abgphy_info_t;
};
typedef struct _nphy_iq_comp {
struct nphy_iq_comp {
s16 a0;
s16 b0;
s16 a1;
s16 b1;
} nphy_iq_comp_t;
};
typedef struct _nphy_txpwrindex {
struct nphy_txpwrindex {
s8 index;
s8 index_internal;
s8 index_internal_save;
@ -431,20 +435,20 @@ typedef struct _nphy_txpwrindex {
u16 iqcomp_a;
u16 iqcomp_b;
u16 locomp;
} phy_txpwrindex_t;
};
typedef struct {
struct txiqcal_cache {
u16 txcal_coeffs_2G[8];
u16 txcal_radio_regs_2G[8];
nphy_iq_comp_t rxcal_coeffs_2G;
struct nphy_iq_comp rxcal_coeffs_2G;
u16 txcal_coeffs_5G[8];
u16 txcal_radio_regs_5G[8];
nphy_iq_comp_t rxcal_coeffs_5G;
} txiqcal_cache_t;
struct nphy_iq_comp rxcal_coeffs_5G;
};
typedef struct _nphy_pwrctrl {
struct nphy_pwrctrl {
s8 max_pwr_2g;
s8 idle_targ_2g;
s16 pwrdet_2g_a1;
@ -471,34 +475,34 @@ typedef struct _nphy_pwrctrl {
s16 a1;
s16 b0;
s16 b1;
} phy_pwrctrl_t;
};
typedef struct _nphy_txgains {
struct nphy_txgains {
u16 txlpf[2];
u16 txgm[2];
u16 pga[2];
u16 pad[2];
u16 ipa[2];
} nphy_txgains_t;
};
#define PHY_NOISEVAR_BUFSIZE 10
typedef struct _nphy_noisevar_buf {
struct nphy_noisevar_buf {
int bufcount;
int tone_id[PHY_NOISEVAR_BUFSIZE];
u32 noise_vars[PHY_NOISEVAR_BUFSIZE];
u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
} phy_noisevar_buf_t;
};
typedef struct {
struct rssical_cache {
u16 rssical_radio_regs_2G[2];
u16 rssical_phyregs_2G[12];
u16 rssical_radio_regs_5G[2];
u16 rssical_phyregs_5G[12];
} rssical_cache_t;
};
typedef struct {
struct lcnphy_cal_results {
u16 txiqlocal_a;
u16 txiqlocal_b;
@ -522,12 +526,12 @@ typedef struct {
u16 rxiqcal_coeff_a0;
u16 rxiqcal_coeff_b0;
} lcnphy_cal_results_t;
};
struct shared_phy {
struct phy_info *phy_head;
struct brcms_phy *phy_head;
uint unit;
si_t *sih;
struct si_pub *sih;
void *physhim;
uint corerev;
u32 machwcap;
@ -561,7 +565,7 @@ struct shared_phy {
bool _rifs_phy;
};
struct phy_pub {
struct brcms_phy_pub {
uint phy_type;
uint phy_rev;
u8 phy_corenum;
@ -574,12 +578,6 @@ struct phy_pub {
bool abgphy_encore;
};
struct phy_info_nphy;
typedef struct phy_info_nphy phy_info_nphy_t;
struct phy_info_lcnphy;
typedef struct phy_info_lcnphy phy_info_lcnphy_t;
struct phy_func_ptr {
initfn_t init;
initfn_t calinit;
@ -594,23 +592,22 @@ struct phy_func_ptr {
rxsigpwrfn_t rxsigpwr;
detachfn_t detach;
};
typedef struct phy_func_ptr phy_func_ptr_t;
struct phy_info {
wlc_phy_t pubpi_ro;
shared_phy_t *sh;
phy_func_ptr_t pi_fptr;
struct brcms_phy {
struct brcms_phy_pub pubpi_ro;
struct shared_phy *sh;
struct phy_func_ptr pi_fptr;
void *pi_ptr;
union {
phy_info_lcnphy_t *pi_lcnphy;
struct brcms_phy_lcnphy *pi_lcnphy;
} u;
bool user_txpwr_at_rfport;
d11regs_t *regs;
struct phy_info *next;
struct brcms_phy *next;
char *vars;
wlc_phy_t pubpi;
struct brcms_phy_pub pubpi;
bool do_initcal;
bool phytest_on;
@ -653,8 +650,8 @@ struct phy_info {
s8 tx_power_offset[TXP_NUM_RATES];
u8 tx_power_target[TXP_NUM_RATES];
srom_fem_t srom_fem2g;
srom_fem_t srom_fem5g;
struct brcms_phy_srom_fem srom_fem2g;
struct brcms_phy_srom_fem srom_fem5g;
u8 tx_power_max;
u8 tx_power_max_rate_ind;
@ -725,7 +722,8 @@ struct phy_info {
u16 mintxbias;
u16 mintxmag;
lo_complex_abgphy_info_t gphy_locomp_iq[STATIC_NUM_RF][STATIC_NUM_BB];
struct lo_complex_abgphy_info gphy_locomp_iq
[STATIC_NUM_RF][STATIC_NUM_BB];
s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
u16 gain_table[TX_GAIN_TABLE_LENGTH];
bool loopback_gain;
@ -783,8 +781,8 @@ struct phy_info {
u32 nphy_bb_mult_save;
u16 nphy_txiqlocal_bestc[11];
bool nphy_txiqlocal_coeffsvalid;
phy_txpwrindex_t nphy_txpwrindex[PHY_CORE_NUM_2];
phy_pwrctrl_t nphy_pwrctrl_info[PHY_CORE_NUM_2];
struct nphy_txpwrindex nphy_txpwrindex[PHY_CORE_NUM_2];
struct nphy_pwrctrl nphy_pwrctrl_info[PHY_CORE_NUM_2];
u16 cck2gpo;
u32 ofdm2gpo;
u32 ofdm5gpo;
@ -852,8 +850,8 @@ struct phy_info {
bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
s16 nphy_lastcal_temp;
txiqcal_cache_t calibration_cache;
rssical_cache_t rssical_cache;
struct txiqcal_cache calibration_cache;
struct rssical_cache rssical_cache;
u8 nphy_txpwr_idx[2];
u8 nphy_papd_cal_type;
@ -884,7 +882,7 @@ struct phy_info {
u8 nphy_txcal_pwr_idx[2];
u8 nphy_rxcal_pwr_idx[2];
u16 nphy_cal_orig_tx_gain[2];
nphy_txgains_t nphy_cal_target_gain;
struct nphy_txgains nphy_cal_target_gain;
u16 nphy_txcal_bbmult;
u16 nphy_gmval;
@ -895,7 +893,7 @@ struct phy_info {
bool nphy_aband_spurwar_en;
u16 nphy_rccal_value;
u16 nphy_crsminpwr[3];
phy_noisevar_buf_t nphy_saved_noisevars;
struct nphy_noisevar_buf nphy_saved_noisevars;
bool nphy_anarxlpf_adjusted;
bool nphy_crsminpwr_adjusted;
bool nphy_noisevars_adjusted;
@ -939,141 +937,145 @@ struct phy_info {
struct wiphy *wiphy;
};
typedef s32 fixed;
typedef struct _cs32 {
struct _cs32 {
fixed q;
fixed i;
} cs32;
};
typedef struct radio_regs {
struct radio_regs {
u16 address;
u32 init_a;
u32 init_g;
u8 do_init_a;
u8 do_init_g;
} radio_regs_t;
};
typedef struct radio_20xx_regs {
struct radio_20xx_regs {
u16 address;
u8 init;
u8 do_init;
} radio_20xx_regs_t;
};
typedef struct lcnphy_radio_regs {
struct lcnphy_radio_regs {
u16 address;
u8 init_a;
u8 init_g;
u8 do_init_a;
u8 do_init_g;
} lcnphy_radio_regs_t;
};
extern lcnphy_radio_regs_t lcnphy_radio_regs_2064[];
extern lcnphy_radio_regs_t lcnphy_radio_regs_2066[];
extern radio_regs_t regs_2055[], regs_SYN_2056[], regs_TX_2056[],
regs_RX_2056[];
extern radio_regs_t regs_SYN_2056_A1[], regs_TX_2056_A1[], regs_RX_2056_A1[];
extern radio_regs_t regs_SYN_2056_rev5[], regs_TX_2056_rev5[],
regs_RX_2056_rev5[];
extern radio_regs_t regs_SYN_2056_rev6[], regs_TX_2056_rev6[],
regs_RX_2056_rev6[];
extern radio_regs_t regs_SYN_2056_rev7[], regs_TX_2056_rev7[],
regs_RX_2056_rev7[];
extern radio_regs_t regs_SYN_2056_rev8[], regs_TX_2056_rev8[],
regs_RX_2056_rev8[];
extern radio_20xx_regs_t regs_2057_rev4[], regs_2057_rev5[], regs_2057_rev5v1[];
extern radio_20xx_regs_t regs_2057_rev7[], regs_2057_rev8[];
extern struct lcnphy_radio_regs lcnphy_radio_regs_2064[];
extern struct lcnphy_radio_regs lcnphy_radio_regs_2066[];
extern struct radio_regs regs_2055[], regs_SYN_2056[], regs_TX_2056[],
regs_RX_2056[];
extern struct radio_regs regs_SYN_2056_A1[], regs_TX_2056_A1[],
regs_RX_2056_A1[];
extern struct radio_regs regs_SYN_2056_rev5[], regs_TX_2056_rev5[],
regs_RX_2056_rev5[];
extern struct radio_regs regs_SYN_2056_rev6[], regs_TX_2056_rev6[],
regs_RX_2056_rev6[];
extern struct radio_regs regs_SYN_2056_rev7[], regs_TX_2056_rev7[],
regs_RX_2056_rev7[];
extern struct radio_regs regs_SYN_2056_rev8[], regs_TX_2056_rev8[],
regs_RX_2056_rev8[];
extern struct radio_20xx_regs regs_2057_rev4[], regs_2057_rev5[],
regs_2057_rev5v1[];
extern struct radio_20xx_regs regs_2057_rev7[], regs_2057_rev8[];
extern char *phy_getvar(phy_info_t *pi, const char *name);
extern int phy_getintvar(phy_info_t *pi, const char *name);
extern char *phy_getvar(struct brcms_phy *pi, const char *name);
extern int phy_getintvar(struct brcms_phy *pi, const char *name);
#define PHY_GETVAR(pi, name) phy_getvar(pi, name)
#define PHY_GETINTVAR(pi, name) phy_getintvar(pi, name)
extern u16 read_phy_reg(phy_info_t *pi, u16 addr);
extern void write_phy_reg(phy_info_t *pi, u16 addr, u16 val);
extern void and_phy_reg(phy_info_t *pi, u16 addr, u16 val);
extern void or_phy_reg(phy_info_t *pi, u16 addr, u16 val);
extern void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val);
extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr);
extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val);
extern u16 read_radio_reg(phy_info_t *pi, u16 addr);
extern void or_radio_reg(phy_info_t *pi, u16 addr, u16 val);
extern void and_radio_reg(phy_info_t *pi, u16 addr, u16 val);
extern void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask,
extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr);
extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask,
u16 val);
extern void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask);
extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask);
extern void write_radio_reg(phy_info_t *pi, u16 addr, u16 val);
extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
extern void wlc_phyreg_enter(wlc_phy_t *pih);
extern void wlc_phyreg_exit(wlc_phy_t *pih);
extern void wlc_radioreg_enter(wlc_phy_t *pih);
extern void wlc_radioreg_exit(wlc_phy_t *pih);
extern void wlc_phyreg_enter(struct brcms_phy_pub *pih);
extern void wlc_phyreg_exit(struct brcms_phy_pub *pih);
extern void wlc_radioreg_enter(struct brcms_phy_pub *pih);
extern void wlc_radioreg_exit(struct brcms_phy_pub *pih);
extern void wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
extern void wlc_phy_read_table(struct brcms_phy *pi,
const struct phytbl_info *ptbl_info,
u16 tblAddr, u16 tblDataHi,
u16 tblDatalo);
extern void wlc_phy_write_table(phy_info_t *pi,
const phytbl_info_t *ptbl_info, u16 tblAddr,
u16 tblDataHi, u16 tblDatalo);
extern void wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset,
u16 tblAddr, u16 tblDataHi,
extern void wlc_phy_write_table(struct brcms_phy *pi,
const struct phytbl_info *ptbl_info,
u16 tblAddr, u16 tblDataHi, u16 tblDatalo);
extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id,
uint tbl_offset, u16 tblAddr, u16 tblDataHi,
u16 tblDataLo);
extern void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val);
extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val);
extern void write_phy_channel_reg(phy_info_t *pi, uint val);
extern void wlc_phy_txpower_update_shm(phy_info_t *pi);
extern void write_phy_channel_reg(struct brcms_phy *pi, uint val);
extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi);
extern void wlc_phy_cordic(fixed theta, cs32 *val);
extern u8 wlc_phy_nbits(s32 value);
extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi,
radio_20xx_regs_t *radioregs);
extern uint wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs,
extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
struct radio_20xx_regs *radioregs);
extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi,
struct radio_regs *radioregs,
u16 core_offset);
extern void wlc_phy_txpower_ipa_upd(phy_info_t *pi);
extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi);
extern void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on);
extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on);
extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real,
s32 *eps_imag);
extern void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi);
extern void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi);
extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi);
extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi);
extern bool wlc_phy_attach_nphy(phy_info_t *pi);
extern bool wlc_phy_attach_lcnphy(phy_info_t *pi);
extern bool wlc_phy_attach_nphy(struct brcms_phy *pi);
extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi);
extern void wlc_phy_detach_lcnphy(phy_info_t *pi);
extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi);
extern void wlc_phy_init_nphy(phy_info_t *pi);
extern void wlc_phy_init_lcnphy(phy_info_t *pi);
extern void wlc_phy_init_nphy(struct brcms_phy *pi);
extern void wlc_phy_init_lcnphy(struct brcms_phy *pi);
extern void wlc_phy_cal_init_nphy(phy_info_t *pi);
extern void wlc_phy_cal_init_lcnphy(phy_info_t *pi);
extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi);
extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi);
extern void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec);
extern void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec);
extern void wlc_phy_chanspec_set_fixup_lcnphy(phy_info_t *pi,
extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi,
chanspec_t chanspec);
extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi,
chanspec_t chanspec);
extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi,
chanspec_t chanspec);
extern int wlc_phy_channel2freq(uint channel);
extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
extern int wlc_phy_chanspec_bandrange_get(phy_info_t *, chanspec_t);
extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, chanspec_t);
extern void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode);
extern s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi);
extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode);
extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi);
extern void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi);
extern void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi);
extern void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi);
extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi);
extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi);
extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi);
extern void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index);
extern void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable);
extern void wlc_lcnphy_stop_tx_tone(phy_info_t *pi);
extern void wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz,
extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index);
extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable);
extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi);
extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz,
u16 max_val, bool iqcalmode);
extern void wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan,
extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan,
u8 *max_pwr, u8 rate_id);
extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
u8 rate_mcs_end,
@ -1083,21 +1085,21 @@ extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power,
u8 rate_ofdm_end,
u8 rate_mcs_start);
extern u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode);
extern s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode);
extern s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode);
extern s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode);
extern void wlc_phy_carrier_suppress_lcnphy(phy_info_t *pi);
extern void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel);
extern void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode);
extern void wlc_2064_vco_cal(phy_info_t *pi);
extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode);
extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode);
extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode);
extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode);
extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi);
extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel);
extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode);
extern void wlc_2064_vco_cal(struct brcms_phy *pi);
extern void wlc_phy_txpower_recalc_target(phy_info_t *pi);
extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi);
#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18
#define LCNPHY_TX_POWER_TABLE_SIZE 128
#define LCNPHY_MAX_TX_POWER_INDEX (LCNPHY_TX_POWER_TABLE_SIZE - 1)
#define LCNPHY_TBL_ID_TXPWRCTL 0x07
#define LCNPHY_TBL_ID_TXPWRCTL 0x07
#define LCNPHY_TX_PWR_CTRL_OFF 0
#define LCNPHY_TX_PWR_CTRL_SW (0x1 << 15)
#define LCNPHY_TX_PWR_CTRL_HW ((0x1 << 15) | \
@ -1106,36 +1108,39 @@ extern void wlc_phy_txpower_recalc_target(phy_info_t *pi);
#define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001
extern void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti);
extern void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti);
extern void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b);
extern void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq);
extern void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b);
extern u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi);
extern void wlc_lcnphy_get_radio_loft(phy_info_t *pi, u8 *ei0,
extern void wlc_lcnphy_write_table(struct brcms_phy *pi,
const struct phytbl_info *pti);
extern void wlc_lcnphy_read_table(struct brcms_phy *pi,
struct phytbl_info *pti);
extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b);
extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq);
extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b);
extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi);
extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0,
u8 *eq0, u8 *fi0, u8 *fq0);
extern void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode);
extern void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode);
extern bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi);
extern void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi);
extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode);
extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode);
extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi);
extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi);
extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1);
extern void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr,
extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr,
s8 *cck_pwr);
extern void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi);
extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi);
extern s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index);
extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index);
#define NPHY_MAX_HPVGA1_INDEX 10
#define NPHY_DEF_HPVGA1_INDEXLIMIT 7
typedef struct _phy_iq_est {
struct phy_iq_est {
s32 iq_prod;
u32 i_pwr;
u32 q_pwr;
} phy_iq_est_t;
};
extern void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable);
extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode);
extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi,
bool enable);
extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode);
#define wlc_phy_write_table_nphy(pi, pti) wlc_phy_write_table(pi, pti, 0x72, \
0x74, 0x73)
@ -1145,82 +1150,86 @@ extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode);
0x72, 0x74, 0x73)
#define wlc_nphy_table_data_write(pi, w, v) wlc_phy_table_data_write((pi), (w), (v))
extern void wlc_phy_table_read_nphy(phy_info_t *pi, u32, u32 l, u32 o,
extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o,
u32 w, void *d);
extern void wlc_phy_table_write_nphy(phy_info_t *pi, u32, u32, u32,
extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32,
u32, const void *);
#define PHY_IPA(pi) \
((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
(pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
#define WLC_PHY_WAR_PR51571(pi) \
#define BRCMS_PHY_WAR_PR51571(pi) \
if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \
(void)R_REG(&(pi)->regs->maccontrol)
extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype);
extern void wlc_phy_aci_reset_nphy(phy_info_t *pi);
extern void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en);
extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype);
extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi);
extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en);
extern u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint chan);
extern void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on);
extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan);
extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on);
extern void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi);
extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi);
extern void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd);
extern s16 wlc_phy_tempsense_nphy(phy_info_t *pi);
extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd);
extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi);
extern u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val);
extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val);
extern void wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est,
extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
u16 num_samps, u8 wait_time,
u8 wait_for_crs);
extern void wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write,
nphy_iq_comp_t *comp);
extern void wlc_phy_aci_and_noise_reduction_nphy(phy_info_t *pi);
extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
struct nphy_iq_comp *comp);
extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi);
extern void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask);
extern u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih);
extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih,
u8 rxcore_bitmask);
extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih);
extern void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type);
extern void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi);
extern void wlc_phy_txpwr_apply_nphy(phy_info_t *pi);
extern void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi);
extern u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi);
extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type);
extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi);
extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi);
extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi);
extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi);
extern nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi);
extern int wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi);
extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi,
struct nphy_txgains target_gain,
bool full, bool m);
extern int wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi,
struct nphy_txgains target_gain,
u8 type, bool d);
extern void wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask,
extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask,
s8 txpwrindex, bool res);
extern void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core, u8 rssi_type);
extern int wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type,
extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type);
extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type,
s32 *rssi_buf, u8 nsamps);
extern void wlc_phy_rssi_cal_nphy(phy_info_t *pi);
extern int wlc_phy_aci_scan_nphy(phy_info_t *pi);
extern void wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower,
bool debug);
extern int wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val,
extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi);
extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi);
extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi,
s32 dBm_targetpower, bool debug);
extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
u8 mode, u8, bool);
extern void wlc_phy_stopplayback_nphy(phy_info_t *pi);
extern void wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf,
extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi);
extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf,
u8 num_samps);
extern void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi);
extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi);
extern int wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh);
extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi,
struct brcms_d11rxhdr *wlc_rxh);
#define NPHY_TESTPATTERN_BPHY_EVM 0
#define NPHY_TESTPATTERN_BPHY_RFCS 1
extern void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs);
extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs);
void wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset,
void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset,
s8 *ofdmoffset);
extern s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi,
extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi,
chanspec_t chanspec);
extern bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pih);
#endif /* _wlc_phy_int_h_ */
extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih);
#endif /* _BRCM_PHY_INT_H_ */

View File

@ -14,10 +14,12 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _wlc_phy_lcn_h_
#define _wlc_phy_lcn_h_
#ifndef _BRCM_PHY_LCN_H_
#define _BRCM_PHY_LCN_H_
struct phy_info_lcnphy {
#include <types.h>
struct brcms_phy_lcnphy {
int lcnphy_txrf_sp_9_override;
u8 lcnphy_full_cal_channel;
u8 lcnphy_cal_counter;
@ -98,7 +100,7 @@ struct phy_info_lcnphy {
u16 lcnphy_extstxctrl1;
s16 lcnphy_cck_dig_filt_type;
s16 lcnphy_ofdm_dig_filt_type;
lcnphy_cal_results_t lcnphy_cal_results;
struct lcnphy_cal_results lcnphy_cal_results;
u8 lcnphy_psat_pwr;
u8 lcnphy_psat_indx;
@ -116,4 +118,4 @@ struct phy_info_lcnphy {
uint lcnphy_aci_start_time;
s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
};
#endif /* _wlc_phy_lcn_h_ */
#endif /* _BRCM_PHY_LCN_H_ */

View File

@ -14,9 +14,7 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/types.h>
#include "wlc_phy_qmath.h"
#include "phy_qmath.h"
/*
Description: This function make 16 bit unsigned multiplication. To fit the output into

View File

@ -14,8 +14,10 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __QMATH_H__
#define __QMATH_H__
#ifndef _BRCM_QMATH_H_
#define _BRCM_QMATH_H_
#include <types.h>
u16 qm_mulu16(u16 op1, u16 op2);
@ -37,4 +39,4 @@ s16 qm_norm32(s32 op);
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
#endif /* #ifndef __QMATH_H__ */
#endif /* #ifndef _BRCM_QMATH_H_ */

View File

@ -14,8 +14,8 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BCM20XX_H
#define _BCM20XX_H
#ifndef _BRCM_PHY_RADIO_H_
#define _BRCM_PHY_RADIO_H_
#define RADIO_IDCODE 0x01
@ -1530,4 +1530,4 @@
#define RADIO_2057_VCM_MASK 0x7
#endif /* _BCM20XX_H */
#endif /* _BRCM_PHY_RADIO_H_ */

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2010 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef phy_version_h_
#define phy_version_h_
#define PHY_MAJOR_VERSION 1
#define PHY_MINOR_VERSION 82
#define PHY_RC_NUMBER 8
#define PHY_INCREMENTAL_NUMBER 0
#define PHY_BUILD_NUMBER 0
#define PHY_VERSION { 1, 82, 8, 0 }
#define PHY_VERSION_NUM 0x01520800
#define PHY_VERSION_STR "1.82.8.0"
#endif /* phy_version_h_ */

View File

@ -123,13 +123,13 @@
#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_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

View File

@ -14,10 +14,8 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/types.h>
#include <sbhnddma.h>
#include <wlc_phy_int.h>
#include <wlc_phytbl_lcn.h>
#include <types.h>
#include "phytbl_lcn.h"
const u32 dot11lcn_gain_tbl_rev0[] = {
0x00000000,
@ -1507,7 +1505,7 @@ const u32 dot11lcn_gain_tbl_5G[] = {
0x00000000
};
const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = {
const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[] = {
{&dot11lcn_gain_tbl_rev0,
sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
0, 32}
@ -1522,7 +1520,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = {
,
};
const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = {
const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev1[] = {
{&dot11lcn_gain_tbl_rev1,
sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
0, 32}
@ -1537,7 +1535,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = {
,
};
const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
{&dot11lcn_gain_tbl_2G,
sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
32}
@ -1555,7 +1553,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
17, 0, 8}
};
const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
{&dot11lcn_gain_tbl_5G,
sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
32}
@ -1573,7 +1571,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
17, 0, 8}
};
const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
{&dot11lcn_gain_tbl_extlna_2G,
sizeof(dot11lcn_gain_tbl_extlna_2G) /
sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
@ -1591,7 +1589,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
};
const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
{&dot11lcn_gain_tbl_5G,
sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
32}
@ -1610,20 +1608,20 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
};
const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
const u32 dot11lcnphytbl_rx_gain_info_sz_rev1 =
sizeof(dot11lcnphytbl_rx_gain_info_rev1) /
sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]);
sizeof(dot11lcnphytbl_rx_gain_info_rev1) /
sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]);
const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
0x014d,
@ -2775,7 +2773,7 @@ const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
0x00080000,
};
const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = {
const struct phytbl_info dot11lcnphytbl_info_rev0[] = {
{&dot11lcn_min_sig_sq_tbl_rev0,
sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
@ -2834,34 +2832,35 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = {
,
};
const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313 = {
const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = {
&dot11lcn_sw_ctrl_tbl_4313_rev0,
sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
};
const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa = {
const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = {
&dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
};
const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
&dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
};
const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
&dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
};
const u32 dot11lcnphytbl_info_sz_rev0 =
sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
const struct lcnphy_tx_gain_tbl_entry
dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
{3, 0, 31, 0, 72,}
,
{3, 0, 31, 0, 70,}
@ -3120,7 +3119,7 @@ const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
,
};
const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
{7, 0, 31, 0, 72,}
,
{7, 0, 31, 0, 70,}
@ -3379,7 +3378,7 @@ const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
,
};
const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
{255, 255, 0xf0, 0, 152,}
,
{255, 255, 0xf0, 0, 147,}

Some files were not shown because too many files have changed in this diff Show More